Codeforces Good Bye 2022: 2023 is NEAR: C. Koxia and Number Theory

Codeforces Good Bye 2022: 2023 is NEAR: C. Koxia and Number Theory

题目链接

题意:给你n个正整数\(\lbrace a_1,a_2,\dots a_n\rbrace\),问是否存在正整数x,使\(\lbrace a_1+x+a_2+x,\dots a_n+x\rbrace\)两两互质。

很显然的结论是,若\(\lbrace a_1,a_2,\dots a_n\rbrace\)有相同数字,那必然加上\(x\)后还相同,于是就不符合两两互质的条件了。这个要预先考虑。

\(b_i=a_i+x\),令\(cnt_{i,k}=|\lbrace a| a\in \lbrace a_1,a_2,\dots a_n\rbrace, a\equiv i \pmod k\rbrace|, i\in [0,k-1]\),即原数组模k剩余i的数的数量。

我们先思考一下\(n=2\)情况。
\(b_i, b_j\)不互质,则存在\(k\in Z^+\),使得\(k|b_i\)\(k|b_j\),即\(b_i\equiv b_j \equiv 0 \pmod k\),所以\(a_i\equiv a_j \equiv -x \pmod k\),不妨令\(-x\equiv t \pmod k,t\in [0,k-1]\),即\(a_i\equiv a_j \equiv t \pmod k\)
可以看出,若\(a_i\equiv a_j \equiv t \pmod k\),那\(\forall x\equiv -t\pmod k\),都会导致\(b_i, b_j\)不互质。

推广到\(n>=2\)但只看因数为\(k\)
一组数\(\lbrace a_1,a_2,\dots a_n\rbrace\),若对\(\forall x,都存在a_i+x\equiv a_j+x \equiv 0 \pmod k\),与之等价的是对\(\forall t \in[0,k-1]\)都可以找到\(a_i\equiv a_j \equiv t \pmod k\)。即对\(\forall i \in [0,k-1], cnt_{i,k} >1\)

我们现在可以看出若存在\(k\in Z^+, \forall i \in [0,k-1], cnt_{i,k} >1\),一定找不出符合条件的x。那反过来,若对\(\forall k\in Z^+, 总存在 i \in [0,k-1], cnt_{i,k} \leqslant1\),是否一定能找出符合条件的x?

是可以的!

首先我们想一想,使\(\forall i \in [0,k-1], cnt_{i,k} >1\)的k,最大为多少,由于\(\lbrace a_1,a_2,\dots a_n\rbrace\)至少要两两成对模k剩余相同的数,而且要填满整个模k完全剩余系,所以满足的k一定有\(2k \leqslant n\),所以所有我们只需要考虑\(k\in [1,\lfloor n/2\rfloor]\)就行了。

若对\(\forall k\in Z^+, 总存在 i \in [0,k-1], cnt_{i,k} \leqslant 1,则取\forall x\equiv i\pmod k\),在只看k这个因数时,不会发生问题。
于是我们考虑把每个符合\(cnt_{i,k} \leqslant1\)\(i,k\)导出的同余式加入方程组,得:

\[\begin{cases} x\equiv t_1 \pmod {k_1}\\ x\equiv t_2 \pmod {k_2}\\ \dots \\ x\equiv t_{\lfloor n/2\rfloor} \pmod {k_{\lfloor n/2\rfloor}} \end{cases} \]

是不是很像中国剩余定理的形式,唯一不同的是,中国剩余定理要满足\(k_i,k_j\)两两互质。所以我们想一下取\(k\)\([i,\lfloor n/2\rfloor]\)的所有质数是否与取\(k\in [i,\lfloor n/2\rfloor]\)是必要的。

显然是的,因为若\(k=pQ,p为质数\),若有\(a_i\equiv a_j \equiv t \pmod k\),则\(k|(a_i-t), k|(a_j-t)\),即\(pQ|(a_i-t), pQ|(a_j-t)\),可得\(p|(a_i-t), p|(a_j-t)\),即\(a_i\equiv a_j \equiv t \pmod p\),所以只需要考虑质数就行了。

于是我们就可以使用中国剩余定理,求出x。

#include<bits/stdc++.h>
#define x first
#define y second
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int N = 110;
int n, m;
LL a[N];

vector<int> primes;
bool not_pri[N];
int cnt[N];

void divide(int n)
{
    for(int i=2;i<=n;i++)
    {
        if(!not_pri[i]) primes.push_back(i);
        for(int j=0;primes[j]*i<=n;j++)
        {
            not_pri[primes[j]*i] = true;
            if(i % primes[j]==0) break;
        }
    }
}


bool solve()
{
    cin >> n;
    map<LL, int> mp;
    for(int i=0;i<n;i++) cin >> a[i];
    for(int i=0;i<n;i++) 
    {
        mp[a[i]] ++;
        if(mp[a[i]] >=2) return false;
    }
    for(int p : primes)
    {
        memset(cnt, 0, sizeof cnt);
        for(int i=0;i<n;i++)
            cnt[a[i]%p] ++;
        bool flag = true;
        for(int i=0;i<p;i++)
            if(cnt[i] < 2)
            {
                flag = false;
                break;
            }
        if(flag) return false;
    }
    return true;
}

int main(void)
{
    divide(100);
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int T = 1;
    cin >>T;
    while(T --)
    {
        if(solve()) cout << "YES" <<'\n';
        else cout << "NO" <<'\n';
    }
    
    return 0;
}
posted @ 2023-01-17 17:03  DarkLights  阅读(14)  评论(0)    收藏  举报