HDU 4704 Sum :http://acm.hdu.edu.cn/showproblem.php?pid=4704
题目描述:
Sum
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 2067 Accepted Submission(s): 861
Problem Description

Sample Input
2
Sample Output
2Hint1. For N = 2, S(1) = S(2) = 1. 2. The input file consists of multiple test cases.
Source
S(k)表示把N分成k个整数和的分法数,此题要求解的是(S(1)+S(2)+...+S(N))mod(10^9+7)的值。
题目分析:
根据隔板定理,把N分成一份的分法数为C(1,n-1),
把N分成两份的分法数为C(2,n-1),
把N分成三份的分法数为C(3,n-1),.... ,
把N分成N份的分法数为C(n-1,n-1)。
设sum=S(1)+S(2)+...+S(N),根据组合数求和公式,sum=2^(n-1)。所以,原式可化为(2^(N-1))mod(10^9+7)
由于N的值比较大,第一步想到的就是要用字符数组来对其进行处理,且由于N比较大,且2和MOD互素,所以要借助于费马小定理求解,2^(MOD-1)modMOD==1,即要看(N-1)中有有多少个(MOD-1),则(N-1)%(MOD-1)的值再对MOD进行快速幂求解即可。
代码实现:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
long long quick_mod(long long a,long long b,long m)
{
long long ans=1;
while(b)
{
if(b&1)
{
ans=(ans*a)%m;
b--;
}
b/=2;
a=a*a%m;
}
return ans;
}
const long long MOD=1000000000+7;
int main()
{
char str[100010];
long long sum;
long long M=MOD-1;
while(scanf("%s",str)!=EOF)
{
int len=strlen(str);
sum=0;
for(int i=0;i<len;i++)
{
sum=sum*10+(str[i]-'0');
sum=sum%M;
}
//cout<<"sum="<<sum<<endl;
printf("%lld\n",quick_mod(2,(sum-1),MOD));
}
return 0;
}