Koxia and Number Theory(数论)

题目链接:

Problem - C - Codeforces

题目大意:

给定一个数组a.问是否存在x,使得gcd(ai+x,aj+x)=1 对任意(1<=x

思路:

首先不难发现,数组不可以出现相同的数字

记bi=ai+x

要满足gcd(bi,bj)=1 对任意(1<=x

问题可以转化为判断:任意x的取值,是否都存在质数p可以整除两个bi。

* 对于一个质数p,假设 ai\equiv aj (mod p),那么x\not\equiv p-amodp(modp)

那么思路就很明显了

对于每个质数p,记录a[i]%p的个数,如果cnt[0]~cnt[p-1]都大于2的话。根据*,可知x无解。

根据容斥原理只需要判断(2-n/2) 之间的质数即可。因为对于大于n/2的质数一定存在cnt[i]<2

Code:

#include
#include
#include
#include
#include
#include
#include
#include 
using namespace std;
#define fi first
#define se second
#define PII pair
#define V vector
#define endl "\n"
typedef long long ll;
typedef unsigned long long ull;
const int N=110;
ll a[N];
int t[N];
void solve()
{
    int n,f=0;
    map mp;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        if(mp.count(a[i])) f=1;
        mp[a[i]]=1;
    }
    if(f) {cout<<"NO\n"; return ;}
    int mi;
    for(int mod=2;mod<=n/2;mod++)
    {
        mi=100;
        memset(t,0,sizeof t);
        for(int i=1;i<=n;i++) 
            t[a[i]%mod]++;
        for(int i=0;i=2) f=1;
    }
    if(f) cout<<"NO\n";
    else cout<<"YES\n";
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int test;
    cin>>test;
    while(test--) solve();
    return 0;    
}

 细心的小伙可能就会问了,不是遍历2-n/2的所有质数吗,代码中直接枚举,对于非质数的判断会不会影响结果吗?

大可不必担心,根据质数分解定理一个合数必然可以分解为一些质数的乘积。

以6为例,6可以分解为2*3。假设6满足x无解的条件,即min(cnti)>=2.

x\equiv i(mod 6),则可以推出 x \equiv i(mod 2) (0<=i<2) 即2也满足x无解的条件,3也是同理 。

你可能感兴趣的:(codeforces,数论,算法)