题意:输入一个N,将N拆分成1-n个数,问有多少种组成方法。
思路:可以用隔板法考虑这个问题,有N个1,就有N-1个空隙,如果是拆分成1个数,那就是放0块隔板即C(N-1,0) (emmm不会打数学式子 ) 2个数字那就是C(N-1,1),以此类推到C(N-1,N-1);那要计算得结果就是 2^(N-1),但由于这个N有100000位,直接快速幂是不可能的,这时候就需要这道题的主角登场了,费马小定理,不了解的可以百度一下。
就是对任意的P,A互质,都有A的(P-1)次方取模于P等于1. 公式表示为: A^(P−1)≡1(mod P)
那么在这道题里我们可以知道 2^(p-1)=1(mod p) , 那我们就只需要求出 t=(N-1)%(p-1), 求2^(t)即可
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 1e9+7;
string n;
ll mypow(ll a, ll k) {
ll ans=1;
while(k) {
if(k&1) {
ans=(ans*a)%mod;
k--;
}
k/=2;
a=a*a%mod;
}
return ans;
}
int main() {
while(cin>>n) {
ll k = n[0]-'0';
for(ll i=1; i<(int)n.size(); ++i)
k = (k*10 +(n[i]-'0')) % (mod-1);
printf("%lld\n",mypow(2,k-1));
}
return 0;
}