UOJ 450 【集训队作业2018】复读机——单位根反演
重要式子:
\( e^x = \sum\limits_{i=0}^{\infty} \frac{x^i}{i!} \)
\( ( e^{a*x} )^{(n)} = a^n * e^{a*x} \)
所以 \( e^{a*x} \) \( [x^n] \) 乘上 n! 就是 \( a^n \) (考虑求 n 次导之后,n 次项系数变成 0 次项系数;x 取值为0即可求得现在的 0 次项系数)
推式子可以看这里:https://blog.csdn.net/As_A_Kid/article/details/88832669
找原根就是枚举 i ,判断 \( i^{\frac{phi(mod)}{p}} \) 是否等于1;其中 p 是 phi(mod) 的每个质因子。
#include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; const int N=5e5+5,mod=19491001,G=7; int upt(int x){while(x>=mod)x-=mod;while(x<0)x+=mod;return x;} int pw(int x,int k) {int ret=1;while(k){if(k&1)ret=(ll)ret*x%mod;x=(ll)x*x%mod;k>>=1;}return ret;} int n,k,op,jc[N],jcn[N]; void init() { jc[0]=1;for(int i=1;i<=k;i++)jc[i]=(ll)jc[i-1]*i%mod; jcn[k]=pw(jc[k],mod-2); for(int i=k-1;i>=0;i--)jcn[i]=(ll)jcn[i+1]*(i+1)%mod; } int C(int n,int m) {return (ll)jc[n]*jcn[m]%mod*jcn[n-m]%mod;} int main() { scanf("%d%d%d",&n,&k,&op); if(op==1){ printf("%d\n",pw(k,n));return 0;} init(); if(op==2) { int ans=0; for(int i=0;i<=k;i++) ans=(ans+(ll)C(k,i)*pw(upt(2*i-k),n))%mod; ans=(ll)ans*pw(2,mod-1-k)%mod; printf("%d\n",ans); return 0; } int w0=1,w1=pw(G,(mod-1)/3),w2=(ll)w1*w1%mod,ans=0; for(int i=0;i<=k;i++) { int tp=0; for(int j=0;j<=k-i;j++) { int tp2=(i+(ll)j*w1)%mod; tp2=(tp2+(ll)(k-i-j)*w2)%mod; tp=(tp+(ll)C(k-i,j)*pw(tp2,n))%mod; } ans=(ans+(ll)tp*C(k,i))%mod; } ans=(ll)ans*pw(3,mod-1-k)%mod; printf("%d\n",ans); return 0; }