HDU 4704 Sum(隔板原理+组合数求和公式+费马小定理+快速幂)
Posted Annetree的博客
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 4704 Sum(隔板原理+组合数求和公式+费马小定理+快速幂)相关的知识,希望对你有一定的参考价值。
题目传送:http://acm.hdu.edu.cn/showproblem.php?pid=4704
Problem Description
Sample Input
2
Sample Output
2
Hint
1. For N = 2, S(1) = S(2) = 1.2. The input file consists of multiple test cases.
题意是输入一个N,求N被分成1个数的结果+被分成2个数的结果+...+被分成N个数的结果,N很大
1.隔板原理
1~N有N个元素,每个元素代表一个1.分成K个数,即在(N-1)个空挡里放置(K-1)块隔板
即求组合数C(N-1,0)+C(N-1,1)+...+C(N-1,N-1)
2.组合数求和公式
C(n,0)+C(n,1)+C(n,2)+.+C(n,n)=2^n
证明如下:
利用二项式定理(a+b)^n=C(n,0)a^n+C(n,1)a^(n-1)b+C(n,2)a^(n-2)b^2 +.+C(n,n)b^n
令a=b=1左边就是2^n
令a=b=1左边就是2^n
所以题目即求2^(n-1)%(1e9+7)
设MOD为1e9+7
3.费马小定理(降幂)
因为N很大,所以需要费马小定理来降幂
费马小定理是假如a是整数,p是质数,且a,p互质(即两者只有一个公约数1),那么a的(p-1)次方除以p的余数恒等于1。
所以可以把(n-1)对(MOD-1)取余 设余数为K 因为2^(MOD-1)%MOD =1
题目即求2^K %MOD
4.快速幂求解
现在K<=MOD,快速幂的复杂度是O(log?N),直接套模板就行
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<string.h> 5 using namespace std; 6 7 #define MOD 1000000007 8 9 long long quick_mod(long long a,long long b,long long m)//快速幂,复杂度log2n 10 { 11 long long ans=1; 12 while(b) 13 { 14 if(b&1) 15 { 16 ans=(ans*a)%m; 17 b--; 18 } 19 b/=2; 20 a=a*a%m; 21 } 22 return ans; 23 } 24 25 int main() 26 { 27 28 char str[100010]; 29 long long sum; 30 int len,i; 31 long long M=MOD-1; 32 while(scanf("%s",str)!=EOF) 33 { 34 len=strlen(str); 35 sum=0; 36 for(i=0;i<len;i++) 37 { 38 sum=sum*10+(str[i]-‘0‘); 39 sum=sum%M;//费马小定理 40 } 41 printf("%lld\n",quick_mod(2,(sum-1),MOD));//快速幂 42 } 43 return 0; 44 }
以上是关于HDU 4704 Sum(隔板原理+组合数求和公式+费马小定理+快速幂)的主要内容,如果未能解决你的问题,请参考以下文章
HDU4704(SummerTrainingDay04-A 欧拉降幂公式)
hdu 4704 Sum (整数和分解+快速幂+费马小定理降幂)