CF1629B GCD Arrays 题解
题意简述:
给定正整数 $l,r,k$,有集合 $A=\{l,l+1,l+2...r-2,r-1,r\}$,
操作:任选两个数,删去一个,并将两个数的乘积加入到集合 $A$ 里。
问: $k$ 次操作后,$\gcd(A)$ 能否不为 $1$。若可以,则输出“YES”;反之,输出“NO”。
Sol:
操作等价于将一个数乘上另一个数 (显然)。
要使 $\gcd(A) \ne 1$ 那么就要使集合 $A$ 内的所有数有共同的质因数 $p$ 。
那么就要进行一步操作,使质因数没有 $p$ 的数乘上质因数有 $p$ 的数,从而使前者的质因数带有 $p$。
容易发现,当 $p=2$ 时,操作数最少,此时将所有奇数乘上一个偶数即可。
所以,最少操作数为原集合中奇数的个数。
所以分类讨论出原区间内奇数的个数,再与 $k$ 比较就可以了。
设原区间共 $s$ 个数,则 $s = r - l +1$。
当 $s \bmod 2 = 1$ 且 $l \bmod 2 = 1$ 时,最小操作数为 $\left\lfloor\dfrac{s}{2}\right\rfloor+1$
当 $s \bmod 2 = 1$ 且 $l \bmod 2 = 0$ 时,最小操作数为 $\left\lfloor\dfrac{s}{2}\right\rfloor$
当 $s \bmod 2 = 0$ 且 $l \bmod 2 = 1$ 时,最小操作数为 $\dfrac{s}{2}$
当 $s \bmod 2 = 0$ 且 $l \bmod 2 = 0$ 时,最小操作数为 $\dfrac{s}{2}$
最后特判一下 $r=1$ 和 $l=r$ 的情况就 AC 了。
代码:
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll unsigned long long
using namespace std;
int main(){
ll t;
cin >> t;
while(t--){
ll l,r,k;
cin >> l >> r >> k;
if(r == 1){
cout << "NO" << endl;
}else if(l == r){
cout << "YES" << endl;
}else{
ll s = r - l + 1;
bool f = l % 2, p = s % 2;
ll limit;
if(f && p)
limit = s / 2 + 1;
else
limit = s / 2;
if(k >= limit)
cout << "YES" << endl;
else
cout << "NO" << endl;
}
}
return 0;
}

浙公网安备 33010602011771号