您的位置:首页 > 其它

hdu 4704 Sum(费马小定理)解题报告

2015-08-01 17:26 441 查看
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.


费马小定理是数论四大定理之一,其他三个也需要知道。

分析:题目要求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);

所以,得到公式An=2^(n-1)后,就很方便了

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

//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

//2^n%m = (2^(n%(m-1)))%m

所以,代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define INF 99999999
#define ll long long
using namespace std;

const int MAX=100000+10;
const int mod=1000000000+7;
char s[MAX];

ll FastPow(ll a,ll k){
ll sum=1;
while(k){
if(k&1)sum=sum*a%mod;
a=a*a%mod;
k>>=1;
}
return sum;
}

int main(){
while(scanf("%s",s)!=EOF){
ll sum=0;
for(int i=0;s[i] != '\0';i++){
sum=(sum*10+s[i]-'0')%(mod-1);
}
ll n=sum-1;
printf("%I64d\n",FastPow(2,n));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: