多校第十场 1009 Sum

来源:互联网 发布:如何在C中调用python 编辑:程序博客网 时间:2024/06/07 07:07

Sum

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 18    Accepted Submission(s): 9


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.
 

Source
2013 Multi-University Training Contest 10
 

Recommend
zhuyuanchen520
题目就是这个意思,所以跟我们前面有一场比赛里面的整数拆分一样,最后的结果就是2^(n-1) ,由于n=10^100000 ,很大,所以普通的快速幂和高精度乘法没法过,数学好的同学肯定一下就能想到这题的解,有了思路代码就不难了,费马小定理是这样说的:

费马小定理是数论中的一个定理:假如a是一个整数,p是一个质数,那么a^p - a 是p的倍数,可以表示为

a^p \equiv a \pmod{p}

如果a不是p的倍数,这个定理也可以写成

a^{p-1} \equiv  1 \pmod{p}
(转自维基百科)我们可以看到mod 是一个大质数(1000000007)所以有:2^(mod-1)%mod=1;而n可以转化为(mod-1)*k+p的形式,所以,
2^(n-1)%mod=2^((mod-1)*k+p)%mod=2^p%mod=2^((n-1)%(mod-1))%mod;这样我们就可以直接用快速幂将结果求出来了。
代码:
#include <cstdio>#include <cstring>#include <algorithm>#define maxn 100003#define mod 1000000007typedef long long LL;LL bit[maxn];char str[maxn];LL quick_pow(LL a,LL p){LL tmp = 1;while(p){if( p&1 ) tmp = tmp * a % mod;a = a * a % mod;p >>= 1;}//printf("%I64d\n",tmp );return tmp;}int main(){int n , i ;  bit[0] = 1;for(i = 1;i < maxn; i++)bit[i] = (bit[i-1]%(mod-1)*10)%(mod-1);//bit[i]表示10^i%(mod-1)while(~scanf("%s",str)){n = strlen(str);i = n-1;str[i]--;while( str[i]<'0'){str[i] = '9';str[i-1]--;i--;}LL res = 0;for(i = n-1 ; i >= 0 ; i--)res = (res + (str[n-i-1] - '0') * bit[i]%(mod-1) )%(mod-1);LL ans = quick_pow( 2, res );printf("%I64d\n",ans );}return 0;}


原创粉丝点击