【HDU2065】"红色病毒"问题 母函数

AC通道:https://vjudge.net/problem/HDU-2065

【题解】

由4种字母组成,A和C只能出现偶数次。

构造指数级生成函数:(1+x/1!+x^2/2!+x^3/3!……)^2*(1+x^2/2!+x^4/4!+x^6/6!……)^2.

前面是B和D的情况,可以任意取,但是相同字母一样,所以要除去排列数。后者是A和C的情况,只能取偶数个情况。

根据泰勒展开,e^x在x0=0点的n阶泰勒多项式为 1+x/1!+x^2/2!+x^3/3!……

而后者也可以进行调整,需要把奇数项去掉,则e^(-x)的展开式为1-x/1!+X^2/2!-X^3/3!……

所以后者可以化简为(e^x+e^(-x))/2。则原式为 (e^x)^2   *  ((e^x*e^(-x))/2)^2

整理得到e^4x+2*e^2x+1。

又由上面的泰勒展开 

e^4x = 1 + (4x)/1! + (4x)^2/2! + (4x)^3/3! + ... + (4x)^n/n!;

e^2x = 1 + (2x)/1! + (2x)^2/2! + (2x)^3/3! + ... + (2x)^n/n!;

对于系数为n的系数为(4^n+2*2^n)/4=4^(n-1)+2^(n-1);

快速幂搞之。

——转自ACM_cxlove

/************
  HDU 2065
  by chty
  2016.12.7
************/
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long ll;
#define FILE "read"
const ll mod=100;
ll T,n;
namespace INIT{
	inline ll read(){
		ll x=0,f=1;  char ch=getchar();
		while(!isdigit(ch))  {if(ch=='-')  f=-1;  ch=getchar();}
		while(isdigit(ch))  {x=x*10+ch-'0';  ch=getchar();}
		return x*f;
	}
}using namespace INIT;
ll fast(ll a,ll b) {ll sum=1;for(;b;b>>=1,a=a*a%mod)if(b&1)sum=sum*a%mod;return sum;}
int main(){
	freopen(FILE".in","r",stdin);
	freopen(FILE".out","w",stdout);
	while(scanf("%lld",&T)&&T>0){
		for(ll i=1;i<=T;i++){
			n=read();
			printf("Case %lld: %lld\n",i,(fast(4,n-1)+fast(2,n-1))%mod);
		}
		printf("\n");
	}
	return 0;
}



你可能感兴趣的:(hdu,母函数)