拯救世界2题解

链接
啊,拯救了一次世界后我们再拯救一次
发现这题的方案是和排列有关的,每种基因出现位置不同视为不同方案,所以使用指数生成函数
一看题面,发现和拯救一差不多,仍然让指数为使用个数,系数为答案,列出如下三个方程(注意是三个,一开始用两个推推了个寂寞(不过估计也就我这么傻))

[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);
	}
}
原文地址:https://www.cnblogs.com/caijiLYC/p/14354710.html