[HDU2065] "红色病毒"问题 (生成函数)

文章目录

  • 题目描述
  • 样例输入输出
  • 解题思路
  • 参考代码

题目描述

Problem Description
医学界发现的新病毒因其蔓延速度和Internet上传播的"红色病毒"不相上下,被称为"红色病毒",经研究发现,该病毒及其变种的DNA的一条单链中,胞嘧啶,腺嘧啶均是成对出现的。
现在有一长度为N的字符串,满足一下条件:
(1) 字符串仅由A,B,C,D四个字母组成;
(2) A出现偶数次(也可以不出现);
(3) C出现偶数次(也可以不出现);
计算满足条件的字符串个数.
当N=2时,所有满足条件的字符串有如下6个:BB,BD,DB,DD,AA,CC.
由于这个数据肯能非常庞大,你只要给出最后两位数字即可.
Input
每组输入的第一行是一个整数T,表示测试实例的个数,下面是T行数据,每行一个整数N(1<=N<264),当T=0时结束.
Output
对于每个测试实例,输出字符串个数的最后两位,每组输出后跟一个空行.

样例输入输出

Sample Input
4
1
4
20
11
3
14
24
6
0

Sample Output
Case 1: 2
Case 2: 72
Case 3: 32
Case 4: 0

Case 1: 56
Case 2: 72
Case 3: 56

解题思路

生成函数裸题。。。
字母A和字母C只可能出现偶数次,而且同种字母之间还要考虑顺序问题,因此,把A,C字母出现的情况写成生成函数的形式就是介样:
( x 0 + x 2 + x 4 + x 6 + . . . ) 2 (x^0 + x^2 + x^4 + x^6 + ... )^2 (x0+x2+x4+x6+...)2
字母B和字母D的出现没有限制,同样要考虑顺序问题,因此,把它们的出现情况写成生成函数的形式如下:
( x 0 + x 1 + x 2 + x 3 + . . . ) 2 (x^0 + x^1 + x^2 + x^3 + ...)^2 (x0+x1+x2+x3+...)2
由此,字符串可能的组成情况写成生成函数如下:
( x 0 + x 2 + x 4 + x 6 + . . . ) 2 ( x 0 + x 1 + x 2 + x 3 + . . . ) 2 (x^0 + x^2 + x^4 + x^6 + ... )^2(x^0 + x^1 + x^2 + x^3 + ...)^2 (x0+x2+x4+x6+...)2(x0+x1+x2+x3+...)2
接着,我们把生成函数写成闭形式,即:
( e x − e − x 2 ) 2 ⋅ ( e x ) 2 (\frac{e^x - e^{-x}}{2})^2 · (e^x)^2 (2exex)2(ex)2
将上式去括号:
e 4 x + 2 ⋅ e 2 x + 1 4 \frac{e^{4x}+2 · e^{2x}+1}{4} 4e4x+2e2x+1
然后,再将上面两个带x的项泰勒展开
e 4 x = 1 + 4 x 1 ! + ( 4 x ) 2 2 ! + ( 4 x ) 3 3 ! + ( 4 x ) 4 4 ! + . . . + ( 4 x ) n n ! + . . . e^{4x} = 1 + \frac{4x}{1!} + \frac{(4x)^2}{2!} + \frac{(4x)^3}{3!} + \frac{(4x)^4}{4!} + ... + \frac{(4x)^n}{n!} + ... e4x=1+1!4x+2!(4x)2+3!(4x)3+4!(4x)4+...+n!(4x)n+...
e 2 x = 1 + 2 x 1 ! + ( 2 x ) 2 2 ! + ( 2 x ) 3 3 ! + ( 2 x ) 4 4 ! + . . . + ( 2 x ) n n ! + . . . e^{2x} = 1 + \frac{2x}{1!} + \frac{(2x)^2}{2!} + \frac{(2x)^3}{3!} + \frac{(2x)^4}{4!} + ... + \frac{(2x)^n}{n!} + ... e2x=1+1!2x+2!(2x)2+3!(2x)3+4!(2x)4+...+n!(2x)n+...
得到其中幂为n的项的系数和,即: a n s w e r = 4 n + 2 × 2 n 4 = 4 n − 1 + 2 n − 1 answer = \frac{4^n + 2 × 2^n}{4} = 4^{n - 1} + 2^{n - 1} answer=44n+2×2n=4n1+2n1
最后再套快速幂即可(稍稍注意一下n的范围,1<=N<264,要用long long

参考代码

#include 
#include 
using namespace std;

const int N = 100;
const int mod = 100;
int T; long long n;

inline int qkpow (int x, long long y) {
	int res = 1;
	for (; y; y >>= 1, x = (x * x) % mod)
		if (y & 1) res = (res * x) % mod; 
	return res;
}

int main () {
	while (scanf ("%d", &T) && T) {
		int Kase = 0;
		while (T --) {
			scanf ("%lld", &n);
			printf ("Case %d: %d\n", ++ Kase, ( qkpow (2, n - 1) + qkpow (4, n - 1) ) % mod);
		}
		putchar ('\n');
	}
	return 0;
}

你可能感兴趣的:([HDU2065] "红色病毒"问题 (生成函数))