2021牛客多校H - Hash Function (FTT)

题意

source

题解

如果存在\(a \equiv b \ {\rm mod} \ M\),即\(a-b \equiv 0 \ {\rm mod} \ M\)​,等价于\(a-b=kM\)。所以如果能求出所有可能的差值,就可以用O(nlogn)复杂度解决。

\(f_i\)代表数\(i\)能够被表示,那么只需用\(f\)和{\(f_{500000-0}, f_{500000-1},f_{500000-2},...\)}卷积即可。卷积后如果\(f_{50000-i}\)大于0,代表存在差值为\(i\)

最后从小到大枚举答案M,直到不存在差值为M的倍数。如果都存在,则答案就是500001。

#include <bits/stdc++.h>
#include <cmath>
#include <complex>

#define endl '\n'
#define IOS std::ios::sync_with_stdio(0); cin.tie(0); cout.tie(0)
#define FILE freopen(".//data_generator//in.txt","r",stdin),freopen("res.txt","w",stdout)
#define FI freopen(".//data_generator//in.txt","r",stdin)
#define FO freopen("res.txt","w",stdout)
#define mp make_pair
#define seteps(N) fixed << setprecision(N)
typedef long long ll;

using namespace std;
/*-----------------------------------------------------------------*/

ll gcd(ll a, ll b) {
    return b ? gcd(b, a % b) : a;
}
#define INF 0x3f3f3f3f
double PI = acos(-1);


typedef std::complex<double> Complex;  // STL complex

const Complex I(0, 1);  // i
const int N = 2e6;
const int M = 5e5;

Complex tmp[N];
Complex f1[N], f2[N];
bool flag[M + 10];
int rev[N + 10];

void change(Complex y[], int len) { // 蝴蝶变换
    for(int i = 0; i < len; ++i) {
        rev[i] = rev[i >> 1] >> 1;
        if(i & 1) {
            rev[i] |= len >> 1;
        }
    }
    for(int i = 0; i < len; ++i) {
        if(i < rev[i]) {
            swap(y[i], y[rev[i]]);
        }
    }
    return;
}

void fft(Complex y[], int len, int on) {
    change(y, len);
    for(int h = 2; h <= len; h <<= 1) { 
        Complex wn(cos(2 * PI / h), sin(on * 2 * PI / h));
        for(int j = 0; j < len; j += h) {
            Complex w(1, 0);
            for(int k = j; k < j + h / 2; k++) {
              Complex u = y[k];
              Complex t = w * y[k + h / 2];
              y[k] = u + t; 
              y[k + h / 2] = u - t;
              w = w * wn;
            }
        }
    }
    if(on == -1) {
        for(int i = 0; i < len; i++) {
            y[i] /= len;
        }
    }
}


int get(int x) {
    int res = 1;
    while(res < x) {
        res = (res << 1);
    }
    return res;
}

int main() {
    
    IOS;
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++) {
        int v;
        cin >> v;
        f1[v] = Complex(1, 0);
        f2[M - v] = Complex(1, 0);
    }

    int tot = get(2 * M + 1); 
    fft(f1, tot, 1);
    fft(f2, tot, 1);

    for (int i = 0; i < tot; i++) {
        f1[i] *= f2[i];
    }

    fft(f1, tot, -1);

    for (int i = 0; i <= M; i++) {
        flag[i] = (bool)round(f1[M - i].real());
    }
    if(n == 1) cout << 1 << endl;
    else {
        bool f = false;
        for(int i = 2; i <= M; i++) {
            bool ok = true;
            for(int j = i; j <= M; j += i) {
                if(flag[j]) {
                    ok = false;
                    break;
                }
            }
            if(ok) {
                f = true;
                cout << i << endl;
                break;
            }
        }
        if(!f) cout << 500001 << endl;
    }
}
posted @ 2021-08-02 10:56  limil  阅读(173)  评论(0编辑  收藏  举报