• 2021牛客多校H


    题意

    source

    题解

    如果存在(a equiv b { m mod} M),即(a-b equiv 0 { m 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 '
    '
    #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;
        }
    }
    
  • 相关阅读:
    初识 Rabbitmq
    Lambda表达式(C语言-gcc编译器)
    二叉树转换成双向链表
    进程的内存分布
    Linux shell之数组
    Ubuntu 使用Gparted工具扩大第一分区方法步骤
    Android源码编译出错解决办法
    IIC总线解析
    VirtualBox Ubuntu虚拟机串口编程
    ubuntu虚拟机上解决克隆github代码慢的方法
  • 原文地址:https://www.cnblogs.com/limil/p/15089022.html
Copyright © 2020-2023  润新知