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;
}

posted @ 2010-09-15 00:08  菜到不得鸟  阅读(179)  评论(0)    收藏  举报