您的位置:首页 > 其它

POJ 2447 RSA 大数分解+逆元+快速幂

2014-08-11 21:27 381 查看
链接:http://poj.org/problem?id=2447

题意:



思路:Pollard_Rho质数分解,得到两个素数因子,P,Q,求出T,E,快速幂即可得M。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <map>
#include <cstdlib>
#include <queue>
#include <stack>
#include <vector>
#include <ctype.h>
#include <algorithm>
#include <string>
#include <set>
#include <ctime>
#define PI acos(-1.0)
#define maxn 10005
#define INF 0x7fffffff
#define eps 1e-8
#define seed 31
typedef long long LL;
typedef unsigned long long ULL;
using namespace std;
LL extend_gcd(LL a, LL b, LL &x, LL &y)
{
if(b==0)
{
x=1;
y=0;
return a;
}
LL r=extend_gcd(b,a%b,x,y);
LL t=x;
x=y;
y=t-a/b*y;
return r;
}
LL mul_mod(LL a,LL b,LL n)
{
a=a%n;
b=b%n;
LL s=0;
while(b)
{
if(b&1)
s=(s+a)%n;
a=(a<<1)%n;
b=b>>1;
}
return s;
}
LL pow_mod(LL a,LL b,LL n)
{
a=a%n;
LL s=1;
while(b)
{
if(b&1)
s=mul_mod(s,a,n);
a=mul_mod(a,a,n);
b=b>>1;
}
return s;
}
LL gcd(LL a,LL b)
{
if(a==0) return 1;
if(a<0) return gcd(-a,b);
return b==0?a:gcd(b,a%b);
}
LL inv(LL a,LL m)
{
LL d,x,y;
d=extend_gcd(a,m,x,y);
if (d==1)
{
x=(x%m+m)%m;
return x;
}
else return -1;
}
LL Pollard_Rho(LL n)
{
if(!(n&1)) return 2;
while(true)
{
LL x=(LL)rand()%n;
if(x<0)
x=-x;
LL y=x;
LL c=(LL)rand()%n;
if(x<0)
c=-c;
if(c==0||c==2) c=1;
for(int i=1,k=2;; i++)
{
x = mul_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 ;
}
}
}
}
int main()
{
LL C,E,N;
while(~scanf("%lld%lld%lld",&C,&E,&N))
{
LL aa=Pollard_Rho(N);
LL T=(aa-1)*(N/aa-1);
LL D=inv(E,T);
LL M=pow_mod(C,D,N);
printf("%lld\n",M);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  数学