生活随笔
收集整理的這篇文章主要介紹了
2021牛客暑期多校训练营1 H Hash Function FFT\NTT
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
傳送門
文章目錄
題意:
給你一個數組aaa,你需要找一個最小的模數xxx,使得aaa中每個數都模上xxx之后互不相同。
n≤5e5,ai≤5e5,ai!=ajn\le5e5,a_i\le5e5,a_i!=a_jn≤5e5,ai?≤5e5,ai?!=aj?
思路:
考慮兩個數modx\bmod xmodx相等意味著什么,寫成表達式的形式就是ai+x?k=aja_i+x*k=a_jai?+x?k=aj?,也就說我們如果知道每兩個數之間的差,讓后將差的因子篩掉,剩下的最小的數即為答案。
顯然可以用fftfftfft加速上面的求每兩個數之間的差的過程,由于存在負數,所以加一個偏移量即可,讓后對于每個數遍歷一下以他為因數的數看看是否被標記即可,這樣可以避免根號的分解過程。
復雜度O(nlogn)O(nlogn)O(nlogn)
**
#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<map>
#include<cmath>
#include<cctype>
#include<vector>
#include<set>
#include<queue>
#include<algorithm>
#include<sstream>
#include<ctime>
#include<cstdlib>
#include<random>
#include<cassert>
#define X first
#define Y second
#define L (u<<1)
#define R (u<<1|1)
#define pb push_back
#define mk make_pair
#define Mid ((tr[u].l+tr[u].r)>>1)
#define Len(u) (tr[u].r-tr[u].l+1)
#define random(a,b) ((a)+rand()%((b)-(a)+1))
#define db puts("---")
using namespace std
;
typedef long long LL
;
typedef unsigned long long ULL
;
typedef pair
<int,int> PII
;const int N
=6000010,mod
=1e9+7,INF
=0x3f3f3f3f;
const double eps
=1e-6,PI
=acos(-1);int n
;
int rev
[N
],p
[N
];
int bit
,limit
;
int c
[N
];struct Complex
{double x
,y
;Complex
operator + (const Complex
& t
) const { return {x
+t
.x
,y
+t
.y
}; }Complex
operator - (const Complex
& t
) const { return {x
-t
.x
,y
-t
.y
}; }Complex
operator * (const Complex
& t
) const { return {x
*t
.x
-y
*t
.y
,x
*t
.y
+y
*t
.x
}; }
}a
[N
],b
[N
];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 w1
=Complex({cos(PI
/mid
),inv
*sin(PI
/mid
)});for(int i
=0;i
<limit
;i
+=mid
*2) {Complex wk
=Complex({1,0});for(int j
=0;j
<mid
;j
++,wk
=wk
*w1
) {Complex x
=a
[i
+j
],y
=wk
*a
[i
+j
+mid
];a
[i
+j
]=x
+y
; a
[i
+j
+mid
]=x
-y
;}}}
}int main()
{
cin
>>n
;for(int i
=1;i
<=n
;i
++) scanf("%d",&p
[i
]);for(int i
=1;i
<=n
;i
++) {a
[p
[i
]].x
=1;b
[500000-p
[i
]].x
=1;}while((1<<bit
)<=1000000) bit
++;limit
=1<<bit
;for(int i
=0;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
=500000;i
<=1000000;i
++) if((int)(a
[i
].x
/limit
+0.5)>0) c
[i
-500000]=1;for(int i
=n
;;i
++) {bool flag
=true;for(int j
=i
;j
<N
;j
+=i
) if(c
[j
]) { flag
=false; break; }if(flag
) {printf("%d\n",i
);break;}}return 0;
}
總結
以上是生活随笔為你收集整理的2021牛客暑期多校训练营1 H Hash Function FFT\NTT的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。