同余定理 卷积 FFT优化
#include<bits/stdc++.h> using namespace std; using ll=long long; const int maxn=(1<<20)+5; const double PI=acos(-1); struct Complex { double x,y; Complex operator+(const Complex &o) const{return{x+o.x,y+o.y};} Complex operator-(const Complex &o) const{return{x-o.x,y-o.y};} Complex operator*(const Complex &o) const{return{x*o.x-y*o.y,x*o.y+y*o.x};} }A[maxn],B[maxn]; int rev[maxn]; int limit=1; void FFT(Complex *a,int inv){ for(int i=0;i<limit;i++) if(i<rev[i])swap(a[i],a[rev[i]]); for(int mid=1;mid<limit;mid<<=1){ Complex Wn=Complex({cos(PI/mid),inv*sin(PI/mid)}); for(int i=0;i<limit;i+=mid*2){ Complex w=Complex({1,0}); for(int j=0;j<mid;j++,w=w*Wn){ Complex x=a[i+j],y=w*a[i+j+mid]; a[i+j]=x+y,a[i+j+mid]=x-y; } } } if(inv==-1) for(int i=0;i<limit;i++) A[i].x/=limit; } // --------FFT int n; const int Bs=500000; int vis[maxn]; int main(){ cin>>n; for(int i=1;i<=n;i++) { int b; cin>>b; A[b].x=1;//ax^b, 输入的b是次方,1为系数a B[Bs-b].x=1;//用Bs-b表示负数 } int bit=20; limit=1<<20;//limit要大于最高次数 for(int i=1;i<limit;i++) rev[i]=rev[i>>1]>>1|(i&1)<<(bit-1); FFT(A,1),FFT(B,1); for(int i=0;i<limit;i++) A[i]=A[i]*B[i]; FFT(A,-1); for(int i=0;i<=Bs;i++) vis[i]=int(A[i+Bs].x+0.5);//表示系数,因为是减法,加过Bs,大于Bs的符合要求,进行判断是否存在改次方 for(int i=n;;i++) { bool ok=1; for(int j=i;j<=Bs;j+=i) if(vis[j]) {ok=0;break;} if(ok) return cout<<i<<'\n',0; } return 0; }
https://ac.nowcoder.com/acm/contest/11166/H