Problem D Super A^B mod C
Accept: 39 Submit: 363
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
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<ctime>
using namespace std;
//a^b%c=a ^(b%eular(c)+eular(c)) % c;
//求a,b的最大公约数
__int64 gcd(__int64 a,__int64 b)
{
return b==0?a:gcd(b,a%b);
}
//求a*b%c,因为a,b很大,所以要先将b写成二进制数,再加:例如3*7=3*(1+2+4);
__int64 mulmod(__int64 a,__int64 b,__int64 c)
{
__int64 cnt=0,temp=a;
while(b)
{
if(b&1) cnt=(cnt+temp)%c;
temp=(temp+temp)%c;
b>>=1;
}
return cnt;
}
//求a^b%c,再次将b写成二进制形式,例如:3^7=3^1*3^2*3^4;
__int64 powmod(__int64 a,__int64 b,__int64 c)
{
__int64 cnt=1,temp=a;
while(b)
{
if(b&1) cnt=mulmod(cnt,temp,c);//cnt=(cnt*temp)%c;
temp=mulmod(temp,temp,c);//temp=(temp*temp)%c;
b>>=1;
}
return cnt;
}
//Miller-Rabin测试n是否为素数,1表示为素数,0表示非素数
int pri[10]={2,3,5,7,11,13,17,19,23,29};
bool Miller_Rabin(__int64 n)
{
if(n<2) return 0;
if(n==2) return 1;
if(!(n&1)) return 0;
__int64 k=0,m;
m=n-1;
while(m%2==0) m>>=1,k++;//n-1=m*2^k
for(int i=0;i<10;i++)
{
if(pri[i]>=n) return 1;
__int64 a=powmod(pri[i],m,n);
if(a==1) continue;
int j;
for(j=0;j<k;j++)
{
if(a==n-1) break;
a=mulmod(a,a,n);
}
if(j<k) continue;
return 0;
}
return 1;
}
//pollard_rho 大整数分解,给出n的一个非1因子,返回n是为一次没有找到
__int64 pollard_rho(__int64 C,__int64 N)
{
__int64 I, X, Y, K, D;
I = 1;
X = rand() % N;
Y = X;
K = 2;
do
{
I++;
D = gcd(N + Y - X, N);
if (D > 1 && D < N) return D;
if (I == K) Y = X, K *= 2;
X = (mulmod(X, X, N) + N - C) % N;
}while (Y != X);
return N;
}
//找出N的最小质因数
__int64 rho(__int64 N)
{
if (Miller_Rabin(N)) return N;
do
{
__int64 T = pollard_rho(rand() % (N - 1) + 1, N);
if (T < N)
{
__int64 A, B;
A = rho(T);
B = rho(N / T);
return A < B ? A : B;
}
}
while(1);
}
//N分解质因数,这里是所有质因数,有重复的
__int64 AllFac[1100];
int Facnum;
void findrepeatfac(__int64 n)
{
if(Miller_Rabin(n))
{
AllFac[++Facnum]=n;
return ;
}
__int64 factor;
do
{
factor=pollard_rho(rand() % (n - 1) + 1, n);
}while(factor>=n);
findrepeatfac(factor);
findrepeatfac(n/factor);
}
//求N的所有质因数,是除去重复的
__int64 Fac[1100];
int num[1100];
int len;//0-len
void FindFac(__int64 n)
{
len=0;
//初始化
memset(AllFac,0,sizeof(AllFac));
memset(num,0,sizeof(num));
Facnum=0;
findrepeatfac(n);
sort(AllFac+1,AllFac+1+Facnum);
Fac[0]=AllFac[1];
num[0]=1;
for(int i=2;i<=Facnum;i++)
{
if(Fac[len]!=AllFac[i])
{
Fac[++len]=AllFac[i];//important
}
num[len]++;
}
}
//求n的欧拉函数值
__int64 oula(__int64 n)
{
FindFac(n);
__int64 cnt=n;
for(int i=0;i<=len;i++)
{
cnt-=cnt/Fac[i];
}
return cnt;
}
//枚举n的所有因子 cnt
/*__int64 Fac[1100];
int num[1100];
int len;//0-len
*/
__int64 yinzi[100000];
__int64 yinzinum;//初始化在main中(0-yinzinum-1)
void dfs(int id,__int64 cnt)
{
yinzi[yinzinum++]=cnt;
if(id==len+1)
{
return ;
}
__int64 temp=1;
for(int i=0;i<=num[id];i++)
{
dfs(id+1,cnt*temp);
temp*=Fac[id];
}
}
__int64 Mod(char* B,__int64 ou)
{
__int64 cnt=0;
for(int i=0;B[i];i++)
{
cnt=(cnt*10+B[i]-'0')%ou;
}
return cnt;
}
__int64 _pow(__int64 A,__int64 X,__int64 C)
{
if(X==0) return 1;
if(X==1) return A%C;
__int64 cnt=_pow(A,X/2,C);
cnt=cnt*cnt%C;
if(X&1) cnt=cnt*A%C;
return cnt;
}
int main()
{
__int64 A,C;
char B[1100000];
while(scanf("%I64d%s%I64d",&A,B,&C)==3)
{
__int64 ou=oula(C);
__int64 X=Mod(B,ou);
__int64 res=_pow(A,X+ou,C);
printf("%I64d/n",res);
}
return 0;
}
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <math.h>
using namespace std;
//a^b%c=a ^(b%eular(c)+eular(c)) % c;
char s[1000010];
bool is[20000];
int prm[30000];
int totleprm;
__int64 strmod(char *s,__int64 t)
{
__int64 sum=0;
int i,len=strlen(s);
for(i=0;i<len;i++)
{
sum=sum*10+s[i]-'0';
while(sum>=t) sum-=t;
}
return sum;
}
int getprm(__int64 n)
{
int i, j, k = 0;
int s, e = (int)(sqrt(0.0 + n) + 1);
memset(is, 1, sizeof(is));
prm[k++] = 2;
is[0] = is[1] = 0;
for (i = 4; i < n; i +=2) is[i] = 0;
for (i = 3; i < e; i +=2) if(is[i])
{
prm[k++] = i;
for (s = i * 2, j = i * i ; j < n; j +=s)
is[j] = 0;
}
for (; i < n; i +=2)
if (is[i]) prm[k++] = i;
return k;
}
__int64 euler(__int64 n)
{
int count = n;
int i = 2;
for(; i<=n; i++)
if(n % i == 0)
{
count -= count / i;
while(n % i == 0)
n /= i;
}
return count;
}
__int64 product_mod(__int64 a,__int64 b,__int64 c)
{
__int64 ret=0,tmp=a%c;
while(b)
{
if(b&0x1)
if((ret+=tmp)>=c)
ret-=c;
if((tmp<<=1)>=c)
tmp-=c;
b>>=1;
}
return ret;
}
__int64 power_mod(__int64 A, __int64 B, __int64 C)
{
__int64 R = 1, D = A;
while (B )
{
if (B&1) R = product_mod(R, D, C);
D = product_mod(D, D, C);
B >>=1;
}
return R;
}
__int64 phi[10000];
void euler(int maxn)
{
int i;
int j;
for (i = 2; i <= maxn; i++)
phi[i] = i;
for (i = 2; i <= maxn; i+=2)
phi[i] /=2;
for (i = 3; i <= maxn; i+=2)
if (phi[i] == i)
{
for (j = i; j<=maxn; j+=i)
phi[j] = phi[j] / i * (i-1);
}
}
int main()
{
__int64 a;
__int64 c;
totleprm = getprm(10000);
while (scanf("%I64u%s%I64u",&a,s,&c)!=EOF)
{
__int64 b = strmod(s,euler(c))+euler(c);
printf("%I64u/n",power_mod(a,b,c));
}
return 0;
}