题目大意:群里有 k 个不同的复读机。为了庆祝平安夜的到来,在接下来的 n 秒内,它们每秒钟都会选出一位优秀的复读机进行复读。非常滑稽的是,一个复读机只有总共复读了 d 的倍数次才会感到快乐。问有多少种不同的安排方式使得所有的复读机都感到快乐。模数19491001.
题解:以d=3为例,设a,b,c是三个三次单位根,那么答案就是
,二项式定理展开算一下即可。
#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define Rep(i,v) rep(i,0,(int)v.size()-1)
#define lint long long
#define p 19491001
#define g 7
#define ull unsigned lint
#define db long double
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define gc getchar()
#define debug(x) cerr<<#x<<"="<<x
#define sp <<" "
#define ln <<endl
using namespace std;
typedef pair<int,int> pii;
typedef set<int>::iterator sit;
inline int inn()
{
int x,ch;while((ch=gc)<'0'||ch>'9');
x=ch^'0';while((ch=gc)>='0'&&ch<='9')
x=(x<<1)+(x<<3)+(ch^'0');return x;
}
const int N=500010;int fac[N],facinv[N];
inline int fast_pow(int x,int k,int ans=1) { for(;k;k>>=1,x=(lint)x*x%p) (k&1)?ans=(lint)ans*x%p:0;return ans; }
inline int prelude(int n)
{
rep(i,fac[0]=1,n) fac[i]=(lint)fac[i-1]*i%p;
facinv[n]=fast_pow(fac[n],p-2);
for(int i=n-1;i>=0;i--) facinv[i]=(i+1ll)*facinv[i+1]%p;
return 0;
}
inline int C(int n,int m) { return (lint)fac[n]*facinv[m]%p*facinv[n-m]%p; }
namespace subtask1{
inline int solve_d1(int n,int k) { return !printf("%d\n",fast_pow(k,n)); }
}
namespace subtask2{
inline int solve_d2(int n,int k)
{
int ans=0;
rep(i,0,k)
{
int t=2*i-k;if(t<0) t+=p;
ans=(ans+(lint)C(k,i)*fast_pow(t,n))%p;
}
ans=(lint)ans*fast_pow(fast_pow(2,k),p-2)%p;
return !printf("%d\n",ans);
}
}
namespace subtask3{
inline int solve_d3(int n,int k)
{
int w3=fast_pow(g,(p-1)/3),a=1,b=w3,c=(lint)w3*w3%p,ans=0;
rep(i,0,k)
{
int s=0,t;
rep(j,0,k-i)
t=((lint)a*i+(lint)b*j%p+(lint)c*(k-i-j))%p,
s=(s+(lint)C(k-i,j)*fast_pow(t,n))%p;
ans=(ans+(lint)C(k,i)*s)%p;
}
ans=(lint)ans*fast_pow(fast_pow(3,k),p-2)%p;
return !printf("%d\n",ans);
}
}
int main()
{
int n=inn(),k=inn(),d=inn();prelude(k);
if(n%d!=0) return !printf("0\n");
if(d==1) return subtask1::solve_d1(n,k);
if(d==2) return subtask2::solve_d2(n,k);
if(d==3) return subtask3::solve_d3(n,k);
return 0;
}