Koxia and Number Theory(数论)

题目链接:

Problem - C - Codeforces

题目大意:

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

思路:

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

记bi=ai+x

要满足gcd(bi,bj)=1 对任意(1<=x<j<=n)成立,那么对于任意质数p,p至多只可以整除一个bi.否则就会出现gcd(bi,bj)=p的情况。

问题可以转化为判断:任意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<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<cmath>
#include<vector>
#include<map>
#include<unordered_map> 
using namespace std;
#define fi first
#define se second
#define PII pair<int,int>
#define V vector<int>
#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<ll,int> 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<mod;i++)
            mi=min(mi,t[i]);
        if(mi>=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也是同理 。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值