您的位置:首页 > 其它

fzu 1759Super A^B mod C 指数循环节

2016-09-22 15:09 253 查看
[b]Problem 1759 Super A^B mod C[/b]

Time Limit: 1000 mSec Memory Limit : 32768 KB



Problem Description

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



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 4 2 10 1000



Sample Output

1 24



Source

FZU 2009 Summer Training IV--Number Theory

欧拉定理的推广——有关的高次幂取模指数循环节

公式: ax mod(c)=a(x mod phi(c) +phi(c)) mod(c), (x>=phi(c))

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
typedef long long int ll;

const int MAXN = 1e6;
int prime[MAXN+10], cnt = 0;
int a[MAXN+10];

ll pow_mod(ll a, ll n, ll mod){
ll ans = 1;
while(n > 0){
if(n&1) {
n--;
ans = ans*a%mod;
}
n >>= 1;
a = a*a %mod;
}
return ans;
}

void init(){
for(int i = 2; i <= MAXN; i++) a[i] = true;
for(int i = 2; i <= MAXN; i++){
if(a[i]){
prime[++cnt] = i;
}
for(int j = 1; j <= cnt; j++){
if(prime[j]*i > MAXN) break;
a[prime[j]*i] = false;
if(i%prime[j] == 0) break;
}
}
}
ll Euler(ll n){
ll ans = n;
for(int i = 1; i <= cnt && prime[i] <= n; i++){
if(n%prime[i] == 0){
while(n%prime[i] == 0){
n /= prime[i];
}
ans = ans/prime[i]*(prime[i]-1);
}
}
return ans;
}
ll slove(ll a, char s[], ll c, ll mod){
ll sum = 0;
int len = strlen(s);
sum = (s[0] - '0') %mod;
for(int i = 1; i < len; i++){
sum *= 10;
sum = (sum + s[i] - '0')%mod;
}
// printf("sum = %I64d\n", sum);
return pow_mod(a, mod+sum, c);
}
int main(){
ll a, c;
char b[MAXN+10];
init();
while(scanf("%I64d%s%I64d", &a, b, &c) != EOF){
ll p = Euler(c);
// printf("p = %I64d\n", p);
printf("%I64d\n", slove(a, b, c, p));
}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: