hdu2065"红色病毒"问题(指数母函数+快速幂取模)
"红色病毒"问题
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 9329 Accepted Submission(s): 3816
现在有一长度为N的字符串,满足一下条件:
(1) 字符串仅由A,B,C,D四个字母组成;
(2) A出现偶数次(也可以不出现);
(3) C出现偶数次(也可以不出现);
计算满足条件的字符串个数.
当N=2时,所有满足条件的字符串有如下6个:BB,BD,DB,DD,AA,CC.
由于这个数据肯能非常庞大,你只要给出最后两位数字即可.
用母函数来做
A:(1 + x^2/1! + x^4/2! + ….);
B:(1 + x/1! + x^2/2! + x^3/3! + …);
C:(1 + x^2/1! + x^4/2! + ….);
D:(1 + x/1! + x^2/2! + x^3/3! + …);
可以得到
G(x) = (1 + x^2/1! + x^4/2! + ….)2 * (1 + x/1! + x^2/2! + x^3/3! + …)2;
由泰勒展开式
ex = 1 + x/1! + x^2/2! + x^3/3! + …
e-x = 1 - x/1! + x^2/2! - x^3/3! + …
得到
G(x) = e^2x + ((e^x + e^-x)/2)2;
= (1/4) * (^e2x + 1)2
= (1/4) * (e^4x + 2*e^2x + 1);
又因为:
e4x = 1 + (4x)/1! + (4x)^2/2! + (4x)^3/3! + … + (4x)^n/n!;
e2x = 1 + (2x)/1! + (2x)^2/2! + (2x)^3/3! + … + (2x)^n/n!;
所以:
n次幂的排列数为 (1/4)(4^n + 2*2^n)
化简为(4^(n-1)+2^(n-1))%100
因为数据比较大,所以要用到快速幂取模
1 #include<bits/stdc++.h> 2 using namespace std; 3 long long mod_exp(long long a, long long b, long long c) //快速幂取余a^b%c 4 { 5 long long res, t; 6 res = 1 % c; 7 t = a % c; 8 while (b) 9 { 10 if (b & 1) 11 { 12 res = res * t % c; 13 } 14 t = t * t % c; 15 b >>= 1; 16 } 17 return res; 18 } 19 int main() 20 { 21 int t; 22 while(~scanf("%d",&t),t) 23 { 24 int cases=0; 25 while(t--) 26 { 27 28 cases++; 29 long long n;scanf("%lld",&n); 30 long long ans=(mod_exp(4,n-1,100)+mod_exp(2,n-1,100))%100; 31 printf("Case %d: %lld\n",cases,ans); 32 33 } 34 printf("\n"); 35 } 36 return 0; 37 }
https://blog.csdn.net/weixin_39778570/article/details/82256128