UOJ 450 【集训队作业2018】复读机——单位根反演

题目:http://uoj.ac/problem/450

重要式子:

  \( 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;
}

 

posted on 2019-05-22 17:17  Narh  阅读(113)  评论(0编辑  收藏

导航