hdu 4704 Sum(費馬小定理)解題報告
阿新 • • 發佈:2019-01-09
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,n-1,n-2,...,1,則容易得出An=A0+A1+A2+A3+...+A(n-1);
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; }