HDU - 4704 Sum (费马小定理+快速幂)

Sum

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


 

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   |   We have carefully selected several similar problems for you:  6308 6307 6306 6305 6304 

题目大意:输入一个数n,求pow(2,n-1);

由于n非常大,所以这里要用到费马小定理:a^(p-1)%p == 1%p == 1;//p为素数
所以2^n%m == ( 2^(n%(m-1))*2^(n/(m-1)*(m-1)) )%m == (2^(n%(m-1)))%m * ((2^k)^(m-1))%m == (2^(n%(m-1)))%m;//k=n/(m-1)

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;

const int mod = 1e9+7;
char s[10000010];

/*
由于n非常大,所以这里要用到费马小定理:a^(p-1)%p == 1%p == 1;//p为素数
所以2^n%m == ( 2^(n%(m-1))*2^(n/(m-1)*(m-1)) )%m == (2^(n%(m-1)))%m * ((2^k)^(m-1))%m == (2^(n%(m-1)))%m;//k=n/(m-1)
*/

ll quick_mod(ll a,ll b){//快速幂
    ll ans = 1;
    a %= mod;
    while(b){
        if(b&1){
            ans = ans*a%mod;
            b--;
        }
        b >>= 1;
        a = a*a %mod;
    }
    return ans;
}

int main()
{
    while(cin >> s){//位数很大所以输入的是字符串
        ll sum=0;
        int i;
        for(i=0;s[i];i++)
            sum = (sum*10%(mod-1)+s[i]-'0')%(mod-1);
            //将字符串处理成整数,注意最后得到的整数sum要除以mod-1,所以过程中要除余mod-1,而不是mod
        sum = (sum-1)%(mod-1);
        cout << quick_mod(2,sum) << endl;
    }
    return 0;
}


 

猜你喜欢

转载自blog.csdn.net/weixin_42754600/article/details/81178473