POJ2447 分解因数+扩展欧几里得+高次幂取模
来源:互联网 发布:淘宝女士防晒帽 编辑:程序博客网 时间:2024/05/29 15:58
昨天一天弄明白的pollard-rho启发式因数分解没想到今天就用上了 而且是一次过 感觉好有成就感
题目大意 给你N=P*Q 先把p q从N因数分解出来 得到具体的值 然后(p-1)*(q-1)=t 从而求出t的值
有了t的值 根据e*d(mod t)=1 求出e模t的逆元d 注意求出的逆元可能为负 然后求c^d%n 为m 就是
题目要求的值
这题的解题步骤如下
1根据pollard-rho启发式因数分解 把n分解成两个素数p q;
2(p-1)*(q-1)求出t的值
3通过扩展欧几里得 求e模t的逆元变换为 e*d+t*y=1 求出d的值 此时d可能为负 变成正值
4求出c^d%n 即为答案
最后要感谢GF陪我熬夜 鼓励刺激我让我的模板出的那么快。。。
#include <iostream>#include<cstdio>#include<cstdlib>using namespace std;typedef long long int64;int64 gcd(int64 a,int64 b){ if (a==0) return 1; if(a<0) return gcd(-a,b); if(b==0) return a; return gcd(b,a%b);}int64 modmult(int64 a,int64 b,int64 n)//a*b%n{ a%=n; int64 ret; for(ret=0; b; a=(a<<1)%n,b>>=1) if(b&1) ret=(ret+a)%n; return ret;}int64 modular(int64 a,int64 b,int64 n)//renturn a^b%n{ int64 ans=1; a%=n; while(b) { if(b&1) ans=modmult(ans,a,n),b--; b>>=1; a=modmult(a,a,n); } return ans;}bool witness(int64 a,int64 n)//判断 a^(n-1)=1(mod n){ int t=0; int64 x,xi,temp=n-1; while(temp%2==0) t++,temp/=2; xi=x=modular(a,temp,n); for(int i=1; i<=t; i++) { xi=modmult(xi,xi,n); if(xi==1&&x!=1&&x!=n-1) return 1; x=xi; } if(xi!=1) return 1; return 0;}bool millar_rabin(int64 n,int s){ for(int j=1; j<=s; j++) { int64 a=rand()%(n-1)+1;//a=rand()%(Y-X+1)+X; /*n为X~Y之间的随机数 if(witness(a,n)) return 0; } return 1;}int64 pollard_rho(int64 n,int64 c){ int64 i=1,k=2,x,y; x=rand()%n; y=x; while(1) { i++; x=(modmult(x,x,n)+c)%n; int64 d=gcd(y-x,n); if(d!=1&&d!=n) return d; if(x==y) return n; if(i==k) { y=x; k+=k; } }}int64 factor[100];int tol;void findfac(int64 n){ if(millar_rabin(n,10)) { factor[tol++]=n; return; } int64 p=n; while(p>=n) p=pollard_rho(p,rand()%(n-1)+1); findfac(p); findfac(n/p);}void exgcd(long long a,long long b,long long &d,long long &x,long long &y){ if(b==0) { x=1; y=0; d=a; return; } else { exgcd(b,a%b,d,x,y); long long temp=x; x=y; y=temp-(a/b)*y; }}int main(){ long long c,e,n,d,t,gc,y,m; while(~scanf("%lld%lld%lld",&c,&e,&n)) { tol=0; findfac(n); t=(factor[0]-1)*(factor[1]-1); exgcd(e,t,gc,d,y); d=(d+t)%t; m=modular(c,d,n); printf("%lld\n",m); } return 0;}
- POJ2447 分解因数+扩展欧几里得+高次幂取模
- 分解因数
- 因数分解
- 分解因数
- 因数分解
- 因数分解
- 分解因数
- 质因数分解 PLUS 因数分解
- 素因数分解
- 因数分解问题
- n!分解质因数、因数
- 因数分解问题
- OpenJudge2749:分解因数
- 分解素因数 1
- 分解素因数 2
- 分解素因数 3
- Pollard Rho因数分解
- 2749:分解因数
- 求约数个数最多问题
- C++学习总结
- Linux虚拟服务器 LVS 基础介绍
- 倪齐民加盟《青春风暴》 暗助任容萱脱困境_0
- QQ2013 密码获取(Ring3)
- POJ2447 分解因数+扩展欧几里得+高次幂取模
- TIOBE历年编程语言排行榜对应的最佳IDE
- Filter 配置多个URL-PATTERN
- cocosBuilder
- java.lang.IllegalStateException: getWriter() has already been called for this response问题解决
- hibernate 中inverse
- Real-Time Executive (REX)使用手册
- PLC与WIZNET以太网解决方案
- 一个简单的生成静态页的方法