首页 > 代码库 > POJ 2447
POJ 2447
挺水的一题。其实只要理解了RSA算法,就知道要使用大整数分解的方法来直接模拟了。
不过,要注意两个INT64的数相乘来超范围
#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>#include <stdlib.h>#include <time.h>#define LL __int64 using namespace std;LL e,n,c,p,q,f;int cnt;LL prime[10];LL gcd(LL a,LL b){ if(b==0) return a; return gcd(b,a%b);}LL random(LL nc){ return (LL)((double)rand()/RAND_MAX*nc+0.5);}LL multi(LL a,LL b,LL m){ LL ret=0; while(b>0){ if(b&1) ret=(ret+a)%m; b>>=1; a=(a<<1)%m; } return ret;}LL quick(LL a,LL b,LL m){ LL ans=1; a%=m; while(b){ if(b&1) ans=multi(ans,a,m); b>>=1; a=multi(a,a,m); } return ans;}LL witness(LL a, LL nc){ LL m=nc-1; int j=0; while(!(m&1)){ j++; m>>=1; } LL x=quick(a,m,nc); if(x==1||x==nc-1) return false; while(j--){ x=multi(x,x,nc); if(x==nc-1) return false; } return true;}bool miller_rabin(LL nc){ if(nc<2) return false; if(nc==2) return true; if(!(nc&1)) return false; for(int i=1;i<=10;i++){ LL a=random(nc-2)+1; if(witness(a,nc)) return false; } return true;}LL pollard_rho(LL nc,int inc){ LL x,y,d,i=1,k=2; x=random(nc-1)+1; y=x; while(1){ i++; x=(multi(x,x,nc)+inc)%nc; d=gcd(y-x,nc); if(d>1&&d<nc) return d; if(y==x) return nc; if(i==k){ y=x; k=(k<<1); } }}bool find(LL nc,int k){ if(nc==1) return false; if(miller_rabin(nc)){ p=nc; return true; } LL pe=nc; while(pe>=nc) pe=pollard_rho(pe,k--); if(find(pe,k)) return true;; if(find(nc/pe,k)) return true;;}void exgcd(LL a,LL b,LL &x,LL &y){ if(b==0){ x=1; y=0; return ; } exgcd(b,a%b,x,y); LL tmp=x; x=y; y=tmp-a/b*y;}int main(){ LL x,y; while(scanf("%I64d%I64d%I64d",&c,&e,&n)!=EOF){ srand(time(0)); cnt=0; find(n,201); q=n/p; f=(p-1)*(q-1); exgcd(e,f,x,y); x=(x%f+f)%f; LL ans=quick(c,x,n); printf("%I64d\n",ans); } return 0;}
POJ 2447
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。