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;
}
posted @ 2022-01-24 20:01  象征阳光  阅读(8)  评论(0)    收藏  举报  来源