[数学记录]Uoj#450. 【集训队作业2018】复读机
command_block · · 个人记录
题意 : 对一个长度为
-
d\leq 2,k\leq 5\times10^5 -
d=3,k\leq 1000
所以我们要算的就是
对于
使用二项式定理得到
提取系数得
计算复杂度为
对于
答案是
直接三项式展开
提取系数得
计算复杂度为
#include<algorithm>
#include<cstdio>
#define ll long long
#define mod 19491001
#define MaxK 500500
using namespace std;
ll powM(ll a,int t=mod-2){
ll ret=1;
while(t){
if (t&1)ret=ret*a%mod;
a=a*a%mod;t>>=1;
}return ret;
}
ll fac[MaxK],ifac[MaxK];
ll C(int n,int m)
{return fac[n]*ifac[m]%mod*ifac[n-m]%mod;}
void Init(int lim)
{
fac[0]=1;
for (int i=1;i<=lim;i++)
fac[i]=fac[i-1]*i%mod;
ifac[lim]=powM(fac[lim]);
for (int i=lim;i;i--)
ifac[i-1]=ifac[i]*i%mod;
}
int n,k,d;
int main()
{
scanf("%d%d%d",&n,&k,&d);
if (d==1){
printf("%lld",powM(k,n));
return 0;
}Init(k);
ll ans=0;
if (d==2){
for (int i=0;i<=k;i++)
ans=(ans+C(k,i)*powM(mod+i+i-k,n))%mod;
printf("%lld",ans*powM(2,mod-1-k)%mod);
}else {
ll w=663067,w2=w*w%mod;
for (int i=0;i<=k;i++){
ll sum=0;
for (int j=0;j<=k-i;j++)
sum=(sum+
ifac[j]*ifac[k-i-j]%mod*
powM( (i+w*j+w2*(mod+k-i-j))%mod ,n)
)%mod;
ans=(ans+fac[k]*ifac[i]%mod*sum)%mod;
}printf("%lld",ans*powM(3,mod-1-k)%mod);
}return 0;
}