您的位置:首页 > 其它

FZU1752&1650--A^B mod C--快速幂取模

2016-03-11 11:01 429 查看

     Problem Description

Given A,B,C, You should quickly calculate the result of A^B mod C. (1<=A,B,C<2^63).

Input

There are multiply testcases. Each testcase, there
is one line contains three integers A, B and C, separated by a single space.

Output

For each testcase, output an integer, denotes the result of A^B mod C.

Sample Input

3 2 42 10 1000

Sample Output

124

---------------------------------------------------------
分析:1.a*b mod c = ((a mod c)*(b mod c)) mod c = ((a mod c)*b) mod c
 
           (a + b) mod c = ((a mod c)+( b mod c)) mod c
 
         2.必须使用快速幂
 
         3.必须注意数值范围(1<=A,B,C<2^63),这恰好是long long 的范围(-2^63~2^63-1),但是又怎么保证C在没取模之前的范围在long
long之内?无法保证。所以定义范围应该比long long 更大,所以使用的是unsigned long long(0~2^64-1)。
 
        4.尽管使用了unsigned long long类型,但是在A累乘的时候还是会溢出unsigned long long的范围.所以应该将乘法运算变为加法防止范围的溢出
 
            
#include<iostream>
#include<cstdio>
#define LL unsigned long long
using namespace std;
LL mod;
LL mulit(LL x,LL y){
LL ans = 0;
while(y){
if(y&1){
ans += x;
if(ans >= mod)
ans -= mod;
}
x <<= 1;//x = x + x = 2 * x;
if(x >= mod) x -= mod;
y >>= 1;
}
return ans;
}
LL quickpow(LL x,LL n) {
LL ans = 1;
x = x%mod;
while(n){
if(n&1){//判断n是否为奇数
ans = mulit(ans,x);
}
x = mulit(x,x);
n >>= 1;//相当于n/2
}
return ans;
}
int main(){
LL a,b;
while(~scanf("%I64u%I64u%I64u",&a,&b,&mod)){//注意出入格式,或者直接用cin输入,cout输出,避免格式问题
printf("%I64u\n",quickpow(a,b));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: