UOJ
注意到 d ≤ 3 d\leq 3 d≤3, d = 2 d=2 d=2 时 k ≤ 5 × 1 0 5 k\leq 5\times 10^5 k≤5×105, d = 3 d=3 d=3 时 k ≤ 1000 k\leq 1000 k≤1000,明示分类讨论= =
对于 d = 1 d=1 d=1,答案显然是 k n k^n kn
其他的,我们可以考虑用指数型生成函数,对于每个复读机的生成函数都一样,如果我们设生成函数为 f ( x ) f(x) f(x),那么答案其实就是 f k ( x ) [ n ] f^k(x)[n] fk(x)[n]。
对于 d = 2 d=2 d=2, { 1 , 0 , 1 , 0 , ⋯   } \{1,0,1,0,\cdots\} {1,0,1,0,⋯},它的指数型生成函数是 f ( x ) = e x + e − x 2 f(x)=\frac {e^x+e^{-x}} 2 f(x)=2ex+e−x,那么
f k ( x ) = 1 2 k ( e x + e − x ) k = 1 2 k ∑ i = 0 k ( k i ) e i x e ( i − k ) x = 1 2 k ∑ i = 0 k ( k i ) e ( 2 i − k ) x f^k(x)=\frac 1 {2^k} (e^x+e^{-x})^k=\frac 1 {2^k}\sum_{i=0}^k\binom k i e^{ix}e^{(i-k)x}=\frac 1 {2^k}\sum_{i=0}^k\binom k i e^{(2i-k)x} fk(x)=2k1(ex+e−x)k=2k1i=0∑k(ik)eixe(i−k)x=2k1i=0∑k(ik)e(2i−k)x
而 ( e a x ) [ n ] = a n (e^{ax})[n]=a^n (eax)[n]=an,因此直接暴力枚举 i i i +快速幂即可做到 O ( k log n ) O(k\log n) O(klogn)。
对于 d = 3 d=3 d=3, { 1 , 0 , 0 , 1 , 0 , 0 , 1 , ⋯   } \{1,0,0,1,0,0,1,\cdots\} {1,0,0,1,0,0,1,⋯},好像不会背公式了。。但可以用单位根反演解一个通式
(1) f ( x ) = ∑ i = 0 ∞ [ d ∣ i ] x i i ! = 1 d ∑ i = 0 ∞ ∑ j = 0 d − 1 ( w d j x ) i i ! = 1 d ∑ j = 0 d − 1 e w d j x f(x)=\sum_{i=0}^\infty[d|i]\frac {x^i} {i!}=\frac 1 d\sum_{i=0}^\infty \sum_{j=0}^{d-1} \frac {(w_d^{j} x)^i} {i!}=\frac 1 d\sum_{j=0}^{d-1} e^{w_d^jx}\tag 1 f(x)=i=0∑∞[d∣i]i!xi=d1i=0∑∞j=0∑d−1i!(wdjx)i=d1j=0∑d−1ewdjx(1)
而恰好在 p = 19491001 p=19491001 p=19491001 意义下,可以定义 w 3 = G p − 1 3 w_3=G^{\frac {p-1} {3}} w3=G3p−1。把 d = 3 d=3 d=3 代入 ( 1 ) (1) (1) 式,可以得到:
f k ( x ) = 1 3 k ( e x + e w 3 1 x + e w 3 2 x ) k f^k(x)=\frac 1 {3^k}(e^x+e^{w_3^1x}+e^{w_3^2x})^k fk(x)=3k1(ex+ew31x+ew32x)k
f k ( x ) = 1 3 k ∑ i = 0 k ( k i ) e i x ( e w 3 1 x + e w 3 2 ) k − i f^k(x)=\frac 1 {3^k} \sum_{i=0}^k\binom k i e^{ix}(e^{w_3^1x}+e^{w_3^{2}})^{k-i} fk(x)=3k1i=0∑k(ik)eix(ew31x+ew32)k−i
f k ( x ) = 1 3 k ∑ i = 0 k ( k i ) e i x ( ∑ j = 0 k − i ( k − i j ) e w 3 1 j + w 3 2 ( k − i − j ) ) f^k(x)=\frac 1 {3^k} \sum_{i=0}^k\binom k i e^{ix}\biggl( \sum_{j=0}^{k-i} \binom {k-i} j e^{w_3^1j+w_3^2(k-i-j)} \biggr) fk(x)=3k1i=0∑k(ik)eix(j=0∑k−i(jk−i)ew31j+w32(k−i−j))
然而先求右边括号里的再求左边是有问题的= =只好把所有的幂都合并
f k ( x ) = 1 3 k ∑ i = 0 k ( k i ) ( ∑ j = 0 k − i ( k − i j ) e i x + w 3 1 j x + w 3 2 ( k − i − j ) x ) f^k(x)=\frac 1 {3^k} \sum_{i=0}^k\binom k i \biggl( \sum_{j=0}^{k-i} \binom {k-i} j e^{ix+w_3^1jx+w_3^2(k-i-j)x} \biggr) fk(x)=3k1i=0∑k(ik)(j=0∑k−i(jk−i)eix+w31jx+w32(k−i−j)x)
同样暴力做,时间复杂度 O ( k 2 log n ) O(k^2\log n) O(k2logn)。
#include
using namespace std;
typedef long long ll;
const int maxn=500010,mod=19491001;
const int G=7,w1=18827933,w2=663067;
template <typename Tp> inline int getmin(Tp &x,Tp y){return y<x?x=y,1:0;}
template <typename Tp> inline int getmax(Tp &x,Tp y){return y>x?x=y,1:0;}
template <typename Tp> inline void read(Tp &x)
{
x=0;int f=0;char ch=getchar();
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') f=1,ch=getchar();
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
if(f) x=-x;
}
int n,k,d,ans,fac[maxn],inv[maxn];
int pls(int x,int y){return x+y>=mod?x+y-mod:x+y;}
int dec(int x,int y){return x<y?x-y+mod:x-y;}
int c(int n,int m){return (ll)fac[n]*inv[m]%mod*inv[n-m]%mod;}
int power(int x,int y)
{
int res=1;
for(;y;y>>=1,x=(ll)x*x%mod)
if(y&1)
res=(ll)res*x%mod;
return res;
}
int main()
{
read(n);read(k);read(d);
fac[0]=1;
for(int i=1;i<=k;i++) fac[i]=(ll)fac[i-1]*i%mod;
inv[k]=power(fac[k],mod-2);
for(int i=k-1;~i;i--) inv[i]=(ll)inv[i+1]*(i+1)%mod;
if(d==1) printf("%d\n",power(k,n));
else if(d==2)
{
for(int i=0;i<=k;i++) ans=(ans+(ll)c(k,i)*power(dec(pls(i,i),k),n))%mod;
ans=(ll)ans*power(9745501,k)%mod;
printf("%d\n",ans);
}
else
{
for(int i=0;i<=k;i++)
{
int tmp,sum=0;
for(int j=0;j<=k-i;j++)
{
tmp=(i+(ll)w1*j+(ll)w2*(k-i-j))%mod;
sum=(sum+(ll)c(k-i,j)*power(tmp,n))%mod;
}
ans=(ans+(ll)c(k,i)*sum)%mod;
}
ans=(ll)ans*power(12994001,k)%mod;
printf("%d\n",ans);
}
return 0;
}