【XSY2119】【BZOJ3992】【SDOI2015】序列统计 原根 NTT
2017-08-28 16:40
531 查看
题目大意
有一个集合s,里面的每个数都≥0且<m。问有多少个长度为n的数列满足这个数列所有数的乘积模m为x。答案模1004535809。
n≤109,m≤8000且m是质数。
题解
先求出m的原根g,这样1~m−1中的每个数都能被表示成g的幂。因为gigj=gi+j,这样就可以把乘积转成和,问题转化为问有多少个长度为n的数列满足这个数列所有数的和模m−1为y,fi+1,j=∑fi,kfi,j−k。因为模数是NTT模数,原根为3,所以可以用NTT优化。
ln&exp好像也可以做。
时间复杂度:O(mlogmlogn)
代码
#include<cstdio> #include<cstring> #include<algorithm> #include<cstdlib> #include<ctime> #include<utility> using namespace std; typedef long long ll; typedef pair<int,int> pii; int m; ll p=1004535809; int g; int len=16384; ll a[100010]; ll b[100010]; ll w1[100010]; ll w2[100010]; int rev[100010]; int c[10010]; ll fp(ll a,ll b) { ll s=1; while(b) { if(b&1) s=s*a%p; a=a*a%p; b>>=1; } return s; } int check(int x) { int s=1; int i; for(i=1;i<=m-2;i++) { s=s*x%m; if(s==1) return 0; } return 1; } void ntt(ll *a,int t) { int i,j,k; ll u,v,w,wn; for(i=0;i<len;i++) if(rev[i]<i) swap(a[i],a[rev[i]]); for(i=2;i<=len;i<<=1) { wn=(t==1?w1[i]:w2[i]); for(j=0;j<len;j+=i) { w=1; for(k=j;k<j+i/2;k++) { u=a[k]; v=a[k+i/2]*w%p; a[k]=(u+v)%p; a[k+i/2]=(u-v+p)%p; w=w*wn%p; } } } if(t==-1) { ll inv=fp(len,p-2); for(i=0;i<len;i++) a[i]=a[i]*inv%p; } } void fp(int n) { int i; while(n) { ntt(a,1); if(n&1) { ntt(b,1); for(i=0;i<len;i++) b[i]=b[i]*a[i]%p; ntt(b,-1); for(i=m;i<len;i++) { b[i%m]=(b[i%m]+b[i])%p; b[i]=0; } } for(i=0;i<len;i++) a[i]=a[i]*a[i]%p; ntt(a,-1); for(i=m;i<len;i++) { a[i%m]=(a[i%m]+a[i])%p; a[i]=0; } n>>=1; } } int main() { int n,x,u; scanf("%d%d%d%d",&n,&m,&x,&u); int i; for(i=1;i<m;i++) if(check(i)) g=i; rev[0]=0; for(i=1;i<len;i++) rev[i]=(rev[i/2]>>1)|(i&1?len>>1:0); for(i=2;i<=len;i<<=1) { w1[i]=fp(3,(p-1)/i); w2[i]=fp(w1[i],p-2); } int s=1; for(i=0;i<=m-2;i++) { c[s]=i; s=s*g%m; } int v; memset(a,0,sizeof a); memset(b,0,sizeof b); b[0]=1; for(i=1;i<=u;i++) { scanf("%d",&v); if(!v) continue; a[c[v]]++; } m--; fp(n); printf("%lld\n",b[c[x]]); return 0; }
相关文章推荐
- [BZOJ3992][SDOI2015]序列统计(DP+原根+NTT)
- BZOJ 3992: [SDOI2015]序列统计 倍增dp 原根 NTT
- [NTT 原根 指标 多项式快速幂] BZOJ 3992 [SDOI2015]序列统计
- [原根 + NTT] LOJ#2183 BZOJ3992:「SDOI2015」序列统计
- [BZOJ3992][SDOI2015]序列统计(DP+原根+NTT)
- bzoj3992 [SDOI2015]序列统计(NTT快速幂)
- BZOJ 3992 SDOI 2015 序列统计 NTT 生成函数 计数 原根
- bzoj3992: [SDOI2015]序列统计 NTT+快速幂
- Bzoj3992:[SDOI2015]序列统计:NTT+DP
- BZOJ 3992 [SDOI2015]序列统计 NTT
- 【BZOJ3992】[SDOI2015]序列统计 NTT+多项式快速幂
- [BZOJ3992] [SDOI2015] [NTT] 序列统计
- 【BZOJ】3992 [SDOI2015]序列统计 【离散对数下的NTT】
- BZOJ[3992][SDOI2015]序列统计 生成函数+NTT
- bzoj3992 [SDOI2015]序列统计(从一道题入手NTT)
- 【BZOJ】3992: [SDOI2015]序列统计 NTT+生成函数
- 【 bzoj 3992 】 [SDOI2015]序列统计 - NTT 生成函数
- bzoj 3992: [SDOI2015]序列统计 (NTT+快速幂+DP)
- bzoj 3992: [SDOI2015]序列统计 NTT
- BZOJ 3992 [SDOI2015]序列统计 NTT