洛谷 - P3321 [SDOI2015]序列统计(原根+NTT)
題目鏈接:點擊查看
題目大意:給出一個集合 SSS,集合中的數是 [0,m)[0,m)[0,m) 且互不相同的,問從集合中選 nnn 次數字,且乘積對 mmm 取模后等于 xxx 的方案數有多少
題目分析:
考慮轉移方程,我們設 f[i][j]f[i][j]f[i][j] 為選了 iii 個數后,乘積對 mmm 取余后為 jjj 的方案數,那么自然有 f[i+1][j]=∑ab≡j(modm)f[i][a]?f[i][b]f[i+1][j]=\sum\limits_{ab\equiv j \pmod m}f[i][a]*f[i][b]f[i+1][j]=ab≡j(modm)∑?f[i][a]?f[i][b]
需要注意到本題的 mmm 是一個特別小的質數,不難想到原根,設 ggg 為 mmm 的原根,可以得到一個性質就是 g1,g2,...,gm?1g^1,g^2,...,g^{m-1}g1,g2,...,gm?1 各不相同,且值域屬于 [1,m)[1,m)[1,m)
所以將每個數換成其原根對應的數字后就可以化乘為加了,設 gA≡a(modm)g^A \equiv a \pmod mgA≡a(modm) 更具體的,原轉移方程就可以書寫為: f[i+1][j]=∑gAgB≡gJ(modm)f[i][A]?f[i][B]f[i+1][j]=\sum\limits_{g^Ag^B\equiv g^J \pmod m}f[i][A]*f[i][B]f[i+1][j]=gAgB≡gJ(modm)∑?f[i][A]?f[i][B] 因為 mmm 是質數,所以根據費馬小定理降冪得到:f[i+1][j]=∑gA+B(modm?1)≡gJ(modm)f[i][A]?f[i][B]f[i+1][j]=\sum\limits_{g^{A+B\pmod {m-1}}\equiv g^J \pmod m}f[i][A]*f[i][B]f[i+1][j]=gA+B(modm?1)≡gJ(modm)∑?f[i][A]?f[i][B]
即 f[i+1][j]=∑A+B≡J(modm?1)f[i][A]?f[i][B]f[i+1][j]=\sum\limits_{A+B\equiv J \pmod {m-1}}f[i][A]*f[i][B]f[i+1][j]=A+B≡J(modm?1)∑?f[i][A]?f[i][B]
又因為每層的卷積的轉移方程是相同的,可以用快速冪優化NTT,時間復雜度為 O(m?logm?logn)O(m*logm*logn)O(m?logm?logn)
有幾個小細節需要注意:
代碼:
// Problem: P3321 [SDOI2015]序列統計 // Contest: Luogu // URL: https://www.luogu.com.cn/problem/P3321 // Memory Limit: 125 MB // Time Limit: 1000 ms // // Powered by CP Editor (https://cpeditor.org)// #pragma GCC optimize(2) // #pragma GCC optimize("Ofast","inline","-ffast-math") // #pragma GCC target("avx,sse2,sse3,sse4,mmx") #include<iostream> #include<cstdio> #include<string> #include<ctime> #include<cmath> #include<cstring> #include<algorithm> #include<stack> #include<climits> #include<queue> #include<map> #include<set> #include<sstream> #include<cassert> #include<bitset> #include<list> #include<unordered_map> #define lowbit(x) (x&-x) using namespace std; typedef long long LL; typedef unsigned long long ull; template<typename T> inline void read(T &x) {T f=1;x=0;char ch=getchar();while(0==isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}while(0!=isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();x*=f; } template<typename T> inline void write(T x) {if(x<0){x=~(x-1);putchar('-');}if(x>9)write(x/10);putchar(x%10+'0'); } const int inf=0x3f3f3f3f; const int N=1e6+100; const int mod=1004535809,G=3,Gi=(mod+1)/3; bool vis[8010]; int n,m,limit = 1,L,r[N],p[8010]; LL a[N],ans[N]; inline LL fastpow(LL a, LL k) {LL base = 1;while(k) {if(k & 1) base = (base * a ) % mod;a = (a * a) % mod;k >>= 1;}return base % mod; } inline void NTT(LL *A, int type) {for(int i = 0; i < limit; i++) if(i < r[i]) swap(A[i], A[r[i]]);for(int mid = 1; mid < limit; mid <<= 1) { LL Wn = fastpow( type == 1 ? G : Gi , (mod - 1) / (mid << 1));for(int j = 0; j < limit; j += (mid << 1)) {LL w = 1;for(int k = 0; k < mid; k++, w = (w * Wn) % mod) {int x = A[j + k], y = w * A[j + k + mid] % mod;A[j + k] = (x + y) % mod,A[j + k + mid] = (x - y + mod) % mod;}}}if(type==-1) {LL inv=fastpow(limit,mod-2);for(int i=0;i<limit;i++) {A[i]=(A[i]*inv)%mod;}} } void q_pow(int n) {ans[0]=1;while(n) {NTT(a,1);if(n&1) {NTT(ans,1);for(int i=0;i<limit;i++) {ans[i]=ans[i]*a[i]%mod;}NTT(ans,-1);for(int i=limit-1;i>=m-1;i--) {ans[i-m+1]=(ans[i-m+1]+ans[i])%mod;ans[i]=0;}}for(int i=0;i<limit;i++) {a[i]=a[i]*a[i]%mod;}NTT(a,-1);for(int i=limit-1;i>=m-1;i--) {a[i-m+1]=(a[i-m+1]+a[i])%mod;a[i]=0;}n>>=1;} } int find_root(int mod) {for(int i=2;i<mod;i++){memset(vis,false,sizeof(vis));bool flag=true;int x=i;for(int j=1;j<=mod-1;j++){if(vis[x]){flag=false;break;}vis[x]=true;x=x*i%mod;}if(flag)return i;}return -1; } int main() { #ifndef ONLINE_JUDGE // freopen("data.in.txt","r",stdin); // freopen("data.out.txt","w",stdout); #endif // ios::sync_with_stdio(false);int x,S;read(n),read(m),read(x),read(S);while(limit<=m+m) limit<<=1,L++;for(int i=0;i<limit;i++) r[i]=(r[i>>1]>>1)|((i&1)<<(L-1));int rt=find_root(m);int sum=1;for(int i=1;i<m-1;i++) {sum=sum*rt%m;p[sum]=i;}for(int i=0,x;i<S;i++) {read(x);if(x) {a[p[x]]=1;}}q_pow(n);cout<<ans[p[x]]<<endl;return 0; } 超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生總結
以上是生活随笔為你收集整理的洛谷 - P3321 [SDOI2015]序列统计(原根+NTT)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2021牛客多校7 - xay love
- 下一篇: 2021牛客多校7 - xay love