题目大意:
对于给出的n个互不相同的数,寻找最小的一个模数p使得对于任意ai%p都不相同。
解题思路:
根据同余定理可知,若A-B=C且模数为C的约数,则必然会是A%p=B%p。所以只需要统计出N个数的两两差值即可。考虑用FFT/NTT优化达到O(NlogN)。多项式乘法使得幂次相加,只需要令第ai位为1,另一个多项式中第G-ai位为1即可,枚举从G+1开始。
const int N=2097152+3,P=998244353,G=3;
int n,m,invn,invG,f[N],g[N],tr[N];
inline void in(Re &x)
{
int f=0;
x=0;
char c=getchar();
while(c<'0'||c>'9')
f|=c=='-',c=getchar();
while(c>='0'&&c<='9')
x=(x<<1)+(x<<3)+(c^48),c=getchar();
x=f?-x:x;
}
inline int mi(Re x,Re k)
{
Re s=1;
while(k)
{
if(k&1)
s=(LL)s*x%P;
x=(LL)x*x%P,k>>=1;
}
return s;
}
inline int inv(Re x)
{
return mi(x,P-2);
}
inline void NTT(Re *f,Re n,Re op)
{
for(Re i=0; i<n; ++i)
if(i<tr[i])
swap(f[i],f[tr[i]]);
for(Re p=2; p<=n; p<<=1)
{
Re len=p>>1,w1=mi(op?invG:G,(P-1)/p);
for(Re st=0; st<n; st+=p)
for(Re i=st,base=1; i<=st+len-1; ++i)
{
Re tmp=(LL)base*f[len+i]%P;
f[len+i]=(f[i]-tmp+P)%P,(f[i]+=tmp)%=P,base=(LL)base*w1%P;
}
}
}
inline void times(Re *f,Re n,Re *g,Re m)
{
for(m+=n,n=1; n<=m; n<<=1)
;
invn=inv(n),invG=inv(G);
for(Re i=1; i<n; ++i)
tr[i]=(tr[i>>1]>>1)|((i&1)?n>>1:0);
NTT(f,n,0),NTT(g,n,0);
for(Re i=0; i<n; ++i)
f[i]=(LL)f[i]*g[i]%P;
NTT(f,n,1);
for(Re i=0; i<=m; ++i)
f[i]=(LL)f[i]*invn%P;
}
const int LC=5e5+10;
ll a[500010];
ll fuck[LC+100];
signed main()
{
ll op;
in(op);
ll rnm=0;
for(int i=0; i<op; i++)
{
in(a[i]);
rnm=max(rnm,a[i]);
f[a[i]]=1;
g[LC-a[i]]=1;
}
n=m=LC;
times(f,n,g,m);
int tail=n+m+50;
for(int i=op; i<=tail-LC; i++)
{
if(f[i+LC])
{
for(int j=1; j*j<=i; j++)
{
if(i%j==0)
{
fuck[j]=1;
fuck[i/j]=1;
}
}
}
}
for(int i=op;; i++)
{
if(fuck[i])
continue;
printf("%lld",i);
return 0;
}
}