指数生成函数针对在长度不定的序列中可重复选取数列中的元做排列的问题。
对指数生成函数的概念介绍https://www.douban.com/note/484814211/
思路转载自 http://blog.youkuaiyun.com/ACM_cxlove?viewmode=contents
构造指数级生成函数:(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。
又由上面的泰勒展开
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项x^n/n!的系数为(4^n+2*2^n)/4=4^(n-1)+2^(n-1);
该题还有一个难点(对我这种菜)就是二分求幂了 因为该题数据量大,普通求幂很容易超时
代码如下:刚开始不知道为啥过不了 后面发现冒号后面还有个空格 知道真相的我眼泪掉下来
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include<string>
using namespace std;
#define modify 100
//二分求幂
int pow(int a, long long n){
if (n == 0)
return 1;
int res = 1;
while (n)
{
if (n & 1)
res = (res*a)%modify;
a *= a;
a %= modify;
n >>= 1;//右移一位比直接除二更高效
}
return res;
}
void main()
{
int t;
long long N;
while (cin >> t)
{
if (t == 0)
return;
int i = 1;
while (t--)
{
cin >> N;
cout << "Case " << i++ << ": " << ((pow(4, N - 1) + pow(2, N - 1)) % 100) << endl;
}
cout << endl;
}
}