4704】Sum 【隔板法+費馬小定理降冪】
阿新 • • 發佈:2019-01-09
分析: 我們可以將n劃分為n 個1,然後我們分1就行了。 s(k) 為 從n-1個空中插入k-1個隔板,即C(n-1,k-1),現在要求C(n-1,0)+C(n-1,1)+C(n-1,2)…+C(n-1,n-1) ,由二項式定理公式 C(n,0)+C(n,1)+C(n,2)…C(n,n)= 2^n. 可知我們要求的是2^(n-1)
但是題目中的N太大了,無法計算,所有我們可以用費馬小定理降冪,
費馬小定理為 a^( p - 1) = 1 ( mod p ) 其中p為素數,同時gcd(a,p)==1。
所以 可以有降冪公式 a ^ n % p= a ^ ( n % ( p-1 ) ) %p ,因為不管多少個a^(p-1) 在p的模下都會是1,所以我們找到餘數就行了。同時為了防止(n%(p-1))可能為負數 , 我們可以用 (n%(p-1)+p-1)%(p-1) 來找到最小的正整數餘數。
將n降冪到mod級數,之後我們用快速冪就行了。
補充: 因為費馬小定理是尤拉定理的特殊形式。
尤拉定理 a ^ phi (p) = 1 ( mod p ) ,其中gcd(a,p)==1 即可 。
同樣可以轉化為降冪形式 假如想求 a ^n % mod , 只要gcd(a,mod)==1,那麼我們都可以轉化 a ^ (n % phi(mod)) % mod如果n%phi(mod)也會出現負數的情況,處理方法同費馬小定理的時候。假如mod為素數 , phi(mod)=mod-1,帶入不就是費馬小定理降冪了, 所以啊,都是尤拉定理的特殊形式。
程式碼
#include<bits/stdc++.h>
using namespace std;
typedef pair<int ,int>pii;
#define first fi
#define second se
#define LL long long
#define fread() freopen("in.txt","r",stdin)
#define fwrite() freopen("out.txt","w",stdout)
#define CLOSE() ios_base::sync_with_stdio(false)
const int MAXN = 1e5;
const int MAXM = 1e6;
const int mod = 1e9+7 -1 ; // p - 1
const int inf = 0x3f3f3f3f ;
LL power(LL a,LL b,LL c){
LL s=1,base=a%c;
while(b){
if(1&b) s=s*base%c;
base=base*base%c;
b>>=1;
}
return s;
}
char s[MAXN];
int main(){
CLOSE();
// fread();
// fwrite();
while(scanf("%s",s)!=EOF){
LL k=0;
for(int i=0;s[i];i++)
k=(k*10+s[i]-'0')%mod;
// 注意這裡 k - 1 可能為負數,所以我們要處理下。
printf("%lld\n",power(2ll,(k%mod-1)%mod,mod+1));
}
return 0;
}