Poj 2447 RSA
来源:互联网 发布:java reflectasm 编辑:程序博客网 时间:2024/06/07 03:36
/*** url: http://poj.org/problem?id=2447* stratege: Pollard_Rho整数分解, 快速模取幂, 逆元求解, 扩展欧几里德* Author:Johnsondu (chennyDu)* Time: 2012-10-16 20:06 Around * Status: 10921637a3127456582447Accepted156K235MSC++2096B2012-10-16 19:55:58**//*--------------------------------------------------一开始一直TLE, 最后换了一个整数分解的模板,就过了。--------------------------------------------------*/#include <iostream>#include <cstdio>#include <cmath>#include <algorithm>#include <cstring>using namespace std ;#define LL __int64LL C, E, N, P, Q, T, M, D ;LL gcd (LL a, LL b){ return b ? gcd (b, a%b) : a ;}LL Mulit_mod(LL a,LL b,LL n) //此处即为把乘法转换为加法{ LL ret = 0,temp = a%n; while (b) { if (b&1) ret = ret + temp; if (ret > n) ret -= n; temp <<= 1; if (temp > n) temp -= n; b >>= 1; } return ret;}long int random(){ LL a; a = rand(); a *= rand(); a *= rand(); a *= rand(); return a;}LL Abs (LL x){return x < 0 ? -x : x ;}LL Pollard_Rho(LL n) { if(!(n&1)) return 2; while(true) { LL x=Abs((LL)rand())%n,y=x; LL c=Abs((LL)rand())%n; if(c==0||c==2) c=1; for(int i=1,k=2;;i++) { x = Mulit_mod(x,x,n); if (x >= c) x -= c; else x += n - c ; if (x == n) x = 0 ; if (x == 0) x = n-1; else x --; LL d = gcd (x>y ? x-y: y-x, n); if (d == n) break ; if (d != 1) return d ; if (i == k) { y = x; k <<= 1 ; } } } } void exgcd (LL a, LL b, LL &d, LL &x, LL &y){ if (b == 0) { d = a ; x = 1 ; y = 0 ; return ; } exgcd (b, a%b, d, x, y) ; LL tmp = x ; x = y ; y = tmp - a/b * y ;}LL pow_mod (LL a, LL b, LL Mod){ LL ret = 1 ; while (b) { if (b & 1) ret = Mulit_mod (ret, a, Mod) ; //Multi_mod 把乘法转换为加法,避免超过数据范围 a = Mulit_mod (a, a, Mod) ; b >>= 1 ; } return ret ;}int main (){ LL x, y, d ; while (scanf ("%I64d%I64d%I64d", &C, &E, &N) != EOF) { P = Pollard_Rho (N) ;// 告诉N,通过分解N(已知N为2个素数的乘积) Q = N / P ;// 得到P, Q T = (P-1)*(Q-1) ; // 依题意,得到Q exgcd (E, T, d, x, y) ; // 求逆元(E * D) mod T = 1 D = (x%T + T) % T ; // 此为D的值 M = pow_mod (C, D, N) ; // M = (C ^ D) mod N 快速模取幂,注意数据范围故看前面注释 printf ("%I64d\n", M) ; // 输出 } return 0 ;}