题目链接:https://ac.nowcoder.com/acm/contest/11166/H
题目大意:对于给定的自然数集合S,寻找一个最小的正整数seed,要求S中的自然数对seed取模后没有重复
思路:
(1)对于任意两个不同的自然数x、y,当且仅当|x-y|%seed=0时x%seed=y%seed,因此,我们要寻找的seed不能是S中任意两个数的差的因子
(2)设多项式A(x)=a0x0+a1x1+a2x2+a3x3+……和B(x)=b0x0+b-1x-1+b-2x-2+b-3x-3+……,每一项的系数都为0或1,表示这一项是否存在(a表示作为被减数,b表示作为减数),那么显然A(x)*B(x)的各项系数就可以表示出所有的差
(3)数据量较大,使用FFT处理多项式乘法
(4)如果出现精度问题,换个板子或者换NTT
(5)最后一组样例的结果是500001,注意别被卡在这里
1 #define _USE_MATH_DEFINES 2 #include <stdio.h> 3 #include <stdlib.h> 4 #include <string.h> 5 #include <string> 6 #include <math.h> 7 #include <ctype.h> 8 #include <vector> 9 #include <stack> 10 #include <map> 11 #include <set> 12 #include <algorithm> 13 #include <iostream> 14 #include <limits.h> 15 #include <iomanip> 16 #include <queue> 17 #include <functional> 18 #include<utility> 19 #include<complex> 20 #define el '\n' 21 #define M 1000005 22 const long double C = 0.57721566490153286060651209; 23 const long long N = 1e9+7; 24 #define ll long long 25 #define ull unsigned long long 26 using namespace std; 27 typedef complex<double> cp; 28 const double pi=acos(-1.0); 29 30 ll gcd(ll a,ll b) 31 { 32 if(!b)return a; 33 else 34 return gcd(b,a%b); 35 } 36 37 ll qsm(ll a,ll b) 38 { 39 long long res=1; 40 long long x=a%N; 41 while(b) 42 { 43 if(b&1)res=res%N*x%N; 44 x=x*x%N; 45 b>>=1; 46 } 47 return res; 48 } 49 50 int rev[(1<<21)+5]; 51 void fft(cp *a,int n,int inv) 52 { 53 int bit=0; 54 while((1<<bit)<n)bit++; 55 for(int i=0;i<=n-1;i++) 56 { 57 rev[i]=(rev[i>>1]>>1)|((i&1)<<(bit-1)); 58 if (i<rev[i])swap(a[i],a[rev[i]]); 59 } 60 for(int mid=1;mid<n;mid*=2) 61 { 62 cp temp(cos(pi/mid),inv*sin(pi/mid)); 63 for (int i=0;i<n;i+=mid*2) 64 { 65 cp omega(1,0); 66 for (int j=0;j<mid;j++,omega*=temp) 67 { 68 cp x=a[i+j],y=omega*a[i+j+mid]; 69 a[i+j]=x+y,a[i+j+mid]=x-y; 70 } 71 } 72 } 73 } 74 75 const int MX=500000; 76 const int SZ=1<<21; 77 cp a[SZ+5]; 78 cp b[SZ+5]; 79 int c[SZ+5]; 80 81 int main() 82 { 83 ios::sync_with_stdio(false); 84 cin.tie(0); 85 cout.tie(0); 86 87 int n; 88 cin>>n; 89 for(int i=0;i<n;i++){ 90 int x; 91 cin>>x; 92 a[x]=cp(1,0); 93 b[MX-x]=cp(1,0); 94 } 95 fft(a,SZ>>1,1); 96 fft(b,SZ>>1,1); 97 for(int i=0;i<(SZ>>1);i++)a[i]*=b[i]; 98 fft(a,SZ>>1,-1); 99 for(int i=0;i<(SZ>>1);i++){ 100 int j=a[i].real()/(SZ>>1)+0.5; 101 if(j)c[abs(MX-i)]=1; 102 } 103 for(int i=n;i<=MX;i++){ 104 int flag=true; 105 for(int j=1;j*i<=MX;j++){ 106 if(c[j*i]){flag=false;break;} 107 } 108 if(flag){ 109 cout<<i<<el; 110 break; 111 } 112 } 113 return 0; 114 }
浙公网安备 33010602011771号