pku 2447 RSA(极力推荐)
200MS左右:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
typedef unsigned long long LL;
#define TIMES 10
LL C,E,N,P,Q,phiN;
LL mult_mod(LL a,LL b,LL m) //(a*b)%m
{
a %= m;
b %= m;
LL s=0;
while(b)
{
if(b & 1)
{
s = s + a;
if(s >= m) s -= m;
}
a <<= 1;
if(a >= m) a -= m;
b >>= 1;
}
return s;
}
LL mod_exp(LL a,LL b,LL m) //a^b(mod m)
{
LL s=1;
while(b)
{
if(b & 1) s = mult_mod(s,a,m);
a = mult_mod(a,a,m);
b >>= 1;
}
return s;
}
bool Witness(LL a,LL n)
{
LL u=n-1;
int t=0;
while( ! (u & 1) )
{
t++;
u >>= 1;
}
LL y,x=mod_exp(a,u,n);
while(t--)
{
y = mult_mod(x,x,n);
if(y==1 && x!=1 && x!=n-1) return true;
x = y;
}
if(y != 1) return true;
return false;
}
bool Miller_Rabin(LL n,int T=TIMES)
{
if(n < 2) return false;
if(n == 2) return true;
if( !(n & 1) ) return false;
while(T--)
{
LL a = rand() % (n-1) + 1;
if( Witness(a,n) ) return false;
}
return true;
}
LL gcd(LL a,LL b)
{
LL t;
if(a<b)
{
t = a;
a = b;
b = t;
}
while(b)
{
t = a % b;
a = b;
b = t;
}
return a;
}
LL Pollard_Rho(LL a,LL n)
{
LL x,y,d,i=1,k=2;
y = x = rand() % (n-1) + 1;
while(1)
{
i++;
x = ( mult_mod(x,x,n) + a ) % n;
if(y > x) d = gcd(y-x,n);
else d = gcd(x-y,n);
if(1<d && d<n) return d;
if(y == x) return n;
if(i == k)
{
y = x;
k <<= 1;
}
}
}
void findfac(LL n)
{
if(Miller_Rabin(n))
{
Q = n;
P = N / Q;
return;
}
LL p=n;
while(p >= n) p = Pollard_Rho( rand() % (n-1) + 1 , p );
findfac(p);
findfac(n/p);
}
LL phi(LL n)
{
LL i,s=1;
for(i=2; i*i <= n; i++)
{
if(n % i == 0)
{
s *= (i-1);
n /= i;
while(n % i == 0)
{
s *= i;
n /= i;
}
}
}
if(n > 1) s *= (n-1);
return s;
}
void solve()
{
findfac(N);
phiN = (P-1) * (Q-1);
LL d;
d = mod_exp(E,phi(phiN)-1,phiN); //d is the inverse element of E
/* for(LL y = 1; ; y++)
{
if( (phiN * y + 1) % E == 0 )
{
d = (phiN * y + 1) / E;
break;
}
}*/
printf("%I64d\n",mod_exp(C,d,N));
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("tdata.txt","r",stdin);
#endif
srand(unsigned(time(0)));
while(scanf("%I64d %I64d %I64d",&C,&E,&N)!=EOF)
{
solve();
}
return 0;
}
浙公网安备 33010602011771号