您的位置:首页 > 其它

HDU 4704 Sum

2015-08-05 15:17 423 查看


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
将其分解,Si 表示将n拆成i个数的方案数


求sum( si ) 1<=i<=n;

分析:

隔板原理, n个木棍,n-1个缝,

分成1份则是C(n-1,0);

分成2份则是C(n-1,1);

分成3份则是C(n-1,2);

...

分成n份则是C(n-1,n-1);

ans = sum( C(n-1,i) ) (0<=i<=n-1)

=2^(n-1);

由于要取模而且 2与 mod
互质,因此可以用费马小定理来降幂


题目要求s1+s2+s3+...+sn;//si表示n划分i个数的n的划分的个数,如n=4,则s1=1,s2=3

假设An=s1+s2+s3+...+sn;

对于n可以先划分第一个数为n,n-1,n-2,...,1,则容易得出An=A0+A1+A2+A3+...+A(n-1);

=>A(n+1)=A0+A1+A2+A3+...+An =>An=2^(n-1);


由于n非常大,所以这里要用到费马小定理:a^(p-1)%p == 1%p == 1;//p为素数

所以2^n%m == ( 2^(n%(m-1))*2^(n/(m-1)*(m-1)) )%m ==(2^(n%(m-1)))%m * ((2^k)^(m-1))%m == (2^(n%(m-1)))%m;//k=n/(m-1)

2^n%m=[b](2^(n%(m-1)))%m[/b]

[b]然后快速幂[/b]





#include <stdio.h>
#include <string.h>
char a[100005];
const __int64 mod=1e9+7;
__int64 b,c;

__int64 qm(__int64 q,__int64 n)
{
c=1;
while(n)
{
if(n&1)
c=c*q%mod;
n>>=1;
q=q*q%mod;
}
return c;
}
int main()
{
while(~scanf("%s",a))
{
b=0;
int l=strlen(a);
for(int i=0;i<l;i++)
b=(b*10+a[i]-'0')%(mod-1);

printf("%I64d\n", qm(2,b-1) );
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: