SumTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 1926 Accepted Submission(s): 803
Problem Description
![]()
Sample Input
Sample Output
|
S(k):找到k个正整数,使它们之和为N,S(k)表示的就是方案数。
题意:给你一个N,让你求出(S(1) + S(2) + ... + S(N)) % (10^9 +7)。
思路:推出公式S(1) + S(2) + ... + S(N) = 2 ^ (N-1),这样就是求解2 ^ (N-1) % (10^9+7)。 N最大可以为10^100000,所以不可以直接求解。
实现:费马小定理a ^ (p-1) = 1 (% p)的应用
首先推出a ^ n = (a ^ (n % (m-1)) * T) (%m)。其中T 是若干个 (a ^ (m-1))相乘的结果,这里我们不用关心有多少个。
由费马小定理a ^ (p-1) = 1(%p),我们可以推出T = 1,这样就得到a ^ n = a ^ (n % (m-1)) (%m)。
显然对于这个公式而言,成立的条件就是费马小定理a ^ (p-1) = 1 (%m)成立的条件——a为整数,p为质数且a不是p的倍数(更深一些欧拉定理:a和p互质即可)。
对于该题,我们需要关心的是可以不可以使用上面的公式。
2^(N-1) % (10^9 + 7),这里2和(10^9+7)满足费马小定理成立的条件。
AC代码:
#include <cstdio>
#include <cstring>
#include <cmath>
#define LL long long
#define MOD 1000000007
LL pow_mod(LL a, LL p, LL n)
{
if(p == 0) return 1;
LL ans = pow_mod(a, p/2, n);
ans = ans * ans % n;
if(p & 1) ans = ans * a % n;
return ans;
}
char str[100000+10];
int main()
{
LL N;
while(scanf("%s", str) != EOF)
{
int len = strlen(str);
N = 0;
for(int i = 0; i < len; i++)
N = (N * 10 + str[i] - '0') % (MOD-1);
N -= 1;
printf("%lld\n", pow_mod(2, N, MOD));
}
return 0;
}