链接
啊,拯救了一次世界后我们再拯救一次
发现这题的方案是和排列有关的,每种基因出现位置不同视为不同方案,所以使用指数生成函数
一看题面,发现和拯救一差不多,仍然让指数为使用个数,系数为答案,列出如下三个方程(注意是三个,一开始用两个推推了个寂寞(不过估计也就我这么傻))
[sum_{i}{frac{x^i}{i!}}\
frac{x}{1!}+frac{x^3}{3!}+frac{x^5}{5!}+……=sum_{i}{frac{x^{2*i+1}}{(2*i+1)!}}\
1+frac{x^2}{2!}+frac{x^4}{4!}+……=sum_{i}{frac{x^{2*i}}{(2*i)!}}\
]
其中第一条和第二条可以将(-x)带入第三条相减或相加后获得,大家都会,不赘述了
先用奇怪公式化简一下
[sum_{i}{frac{x^i}{i!}}=e^x
sum_{i}{frac{x^{2*i+1}}{(2*i+1)!}}=frac{e^x+e^{-x}}{2}\
sum_{i}{frac{x^{2*i}}{(2*i)!}}=frac{e^x-e^{-x}}{2}
]
用乘法原理乘一下,由于那些基因各有(4)种,同样由乘法原理得要将这些柿子四次方
[(e^x)^4*(frac{e^x+e^{-x}}{2})^4*(frac{e^x-e^{-x}}{2})^4\
frac{1}{256}*(e^x*(e^x+e^{-x})*(e^x-e^{-x}))^4\
frac{1}{256}*(e^{3*x}-e^{-x})^4\
]
有趣的是,我们这次采用暴力化简,直接将四次方展开(
[frac{1}{256}*(e^{12*x}-4*e^{8*x}+6*e^{4*x}+e^{-4*x}-4)
]
对于每一项,用奇怪公式反过来推
[frac{1}{256}*(sum{frac{(12*x)^i}{i!}}-4*sum{frac{(8*x)^i}{i!}}+6*sum{frac{(4*x)^i}{i!}}+sum{frac{(-4*x)^i}{i!}}-4)
]
因为答案就是第(n)项的系数,所以代入(n),取出系数
[frac{1}{256}*(frac{12^n}{n!}-4*frac{8^n}{n!}+6*frac{4^n}{n!}+frac{(-4)^n}{n!})
]
因为是(EGF)最后乘上(n!)
就是
[frac{1}{256}*(12^n-4*8^n+6*4^n+(-4)^n)\
81*12^{n-4}-4*8^{n-2}+6*4^{n-4}+(-4)^{n-4}
]
那么这条柿子已经可以做了
但是由于题目恶臭,直接做是会(T)的,此时就需要扩展欧拉定理优化一下
科普一下笑
其实还有不少方法,大家用的都不一样啊
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#define ll long long
using namespace std;
const ll mod=1e9,phi=4e8;
ll n,m,ans,T;
inline ll ksm(ll x,ll k){
ll tmp=1;
while(k>0){
if(k&1)tmp=tmp*x%mod;
x=x*x%mod,k>>=1;
}
return tmp;
}
int main(){
scanf("%lld",&n);
while(n){
ans=0;
if(n<4)printf("0
");
else if(n<phi){
ans=(81*ksm(12,n-4)%mod-ksm(8,n-2)+6*ksm(4,n-4)+ksm(-4,n-4)+mod)%mod;
printf("%lld
",ans);
}
else {
ans=(ans+81*ksm(12,(n-4)%phi+phi)%mod)%mod;
ans=(ans-ksm(8,(n-2)%phi+phi)+mod)%mod;
ans=(ans+6*ksm(4,(n-4)%phi+phi)%mod)%mod;
ll tmp=ksm(4,(n-4)%phi+phi);
if((n-4)%2==1)ans=(ans-tmp+mod)%mod;
else ans=(ans+tmp)%mod;
printf("%lld
",ans);
}
scanf("%lld",&n);
}
}