杭电多校第9场1007 Integers Have Friends 2.0

题意

从一个数列中找出一个子序列,使得子序列每个数模一个数同余,求最长长度。

首先我们容易发现,对于模数2,一个数要么余1,要么余0,那么一个序列至少有n/2个同余的。然后我们写一个式子
a m o d    x = b m o d    x a\mod x = b \mod x amodx=bmodx
a − b m o d    x = 0 a-b \mod x = 0 abmodx=0
即a与b之差即同余的模数,这个余数可以被拆成很多质因数,也是可以使a,b同余的模数。
一个小与4e12的数最多能由11个不同的质因数相乘得(这步可以打表证明)。那么我们就能得到有可能是答案的模数。
再接着思考。我们每次取一个数,他们在答案序列中的几率p >= 1/2,那么取两个数,他们在答案中的概率为p2>=3/4,根据上面的推断,这两个数之差的每一个质因数是构成答案的模数的概率均为3/4,所以我们直接暴力枚举所有质因数x,计算x为模数时的最大答案。这个过程我们计算n次,每次随机两个数,则答案的准确度即为 ( 3 4 ) n (\frac{3}{4})^n 43n

#include "bits/stdc++.h"

using namespace std;
const int N = 4e5;
const int maxn = 3000100;
long long a[N];
long long prime[maxn];
bool sf[maxn];
void sushu() {
    
    
    int num = 0;
    memset(sf, true, sizeof(sf));
    for (int i = 2; i < maxn; i++) {
    
    
        if (sf[i]) prime[++num] = i;
        for (int j = 1; j <= num; j++) {
    
    
            if (1ll * i * prime[j] >= maxn) break;
            sf[i * prime[j]] = false;
            if (i % prime[j] == 0) break;
        }
    }
    sf[1] = false;
    sf[0] = false;  //1 0 特判
}
int n;
int cal(long long mod,long long d)
{
    
    
    int cnt = 0;
    for (int i = 1; i <= n; ++i) {
    
    
        cnt += ((a[i] % mod) == d);
    }
    return cnt;
}
void solve() {
    
    
    int T;
    cin >> T;
    while (T--) {
    
    
        cin >> n;
        for (int i = 1; i <= n; ++i) cin >> a[i];
        int ti = 40;
        int ans = 1;
        while (ti--) {
    
    
            int l,r;
            while (1) {
    
    
                l = rand() % n + 1;
                r = rand() % n + 1;
                if (l != r) break;
            }
            long long d = abs(a[r] - a[l]);
            for (int i = 1;1ll * prime[i] * prime[i] <= d; ++i) {
    
    
                if (d % prime[i] == 0)
                {
    
    
                    ans = max(ans, cal(prime[i],a[l] % prime[i]));
                    while (d % prime[i] == 0) d /= prime[i];
                }
            }
            if (d > 1){
    
    
                ans = max(ans, cal(d,a[l] % d));
            }
        }

        printf("%d\n",ans);
    }
}


signed main() {
    
    
    ios::sync_with_stdio(0);
    srand((unsigned) time(NULL));
    sushu();
    solve();
}

猜你喜欢

转载自blog.csdn.net/weixin_45509601/article/details/119777619
今日推荐