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拆分成1-n个数,问有多少种组成方法。比如Sn=s1+s2+s3+..sn,S(n+1)=s1+s2+s3+...sn+s(n+1);S(n+1)=2Sn.所以Sn=2^(n-1)。但是这个n非常大。我们需要用费马小定理来进行降幂,费马小定理为(a^(p-1))%p = 1,p为素数,题目给的取模的数是1e9+7,是一个素数,可以用费马小定理,(n-1) = k*(p-1)+r;由费马小定理,(a^(p-1))%p = 1,所以可以约去这一部分,最后我们只需要求(a^r)%p, 所以n可以对1e9+6取模,所以我们就把100000位的字符串表示的数用long long 可以表示了,最后由于范围还是1e9+6,所以计算还需要用快熟幂计算,否则会超时。
#include<iostream> #include<stdio.h> #include<string.h> using namespace std; const int M = 1e9 + 7; const int maxn = 1e6 + 10; long long quick_pow(long long a, long long b) { long long res = 1; while(b) { if(b & 1) { res = (res*a)%M; } a = a*a%M; b >>= 1; } return res; } char ch[maxn]; int main() { while(scanf("%s", ch) != EOF) { long long sum = 0; for(int i = 0; i < strlen(ch); ++ i) { sum = (sum*10+(ch[i]-'0'))%(M-1); } sum = (sum+M-2)%(M-1); long long ans = quick_pow(2, sum); printf("%lld\n", ans); } return 0; }