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

  

时间: 2024-10-27 07:44:54

POJ 2447的相关文章

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

链接: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>

POJ 3449 Geometric Shapes --计算几何,线段相交

题意: 给一些多边形或线段,输出与每一个多边形或线段的有哪一些多边形或线段. 解法: 想法不难,直接暴力将所有的图形处理成线段,然后暴力枚举,相交就加入其vector就行了.主要是代码有点麻烦,一步一步来吧. 还有收集了一个线段旋转的函数. Vector Rotate(Point P,Vector A,double rad){ //以P为基准点把向量A旋转rad return Vector(P.x+A.x*cos(rad)-A.y*sin(rad),P.y+A.x*sin(rad)+A.y*co

POJ题目推荐(转载)

POJ推荐50题1.标记“难”和“稍难”的题目可以看看,思考一下,不做要求,当然有能力的同学可以直接切掉.2.标记为A and B的题目是比较相似的题目,建议大家两个一起做,可以对比总结,且二者算作一个题目.3.列表中大约有70个题目.大家选做其中的50道,且每类题目有最低数量限制.4.这里不少题目在BUPT ACM FTP上面都有代码,请大家合理利用资源.5.50个题目要求每个题目都要写总结,养成良好的习惯.6.这个列表的目的在于让大家对各个方面的算法有个了解,也许要求有些苛刻,教条,请大家谅

POJ - 3186 Treats for the Cows (区间DP)

题目链接:http://poj.org/problem?id=3186 题意:给定一组序列,取n次,每次可以取序列最前面的数或最后面的数,第n次出来就乘n,然后求和的最大值. 题解:用dp[i][j]表示i~j区间和的最大值,然后根据这个状态可以从删前和删后转移过来,推出状态转移方程: dp[i][j]=max(dp[i+1][j]+value[i]*k,dp[i][j-1]+value[j]*k) 1 #include <iostream> 2 #include <algorithm&

POJ 2533 - Longest Ordered Subsequence(最长上升子序列) 题解

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置. 题目链接:http://poj.org/problem?id=2533 Description A numeric sequence of ai is ordered if a1 < a2 < ... < aN. Let the subsequence of the given numeric sequence (a1, a2, ..., aN) be any sequence (ai1, ai2, ..., aiK)

POJ——T2271 Guardian of Decency

http://poj.org/problem?id=2771 Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 5932   Accepted: 2463 Description Frank N. Stein is a very conservative high-school teacher. He wants to take some of his students on an excursion, but he is

POJ——T2446 Chessboard

http://poj.org/problem?id=2446 Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 18560   Accepted: 5857 Description Alice and Bob often play games on chessboard. One day, Alice draws a board with size M * N. She wants Bob to use a lot of c

poj 1088 滑雪 DP(dfs的记忆化搜索)

题目地址:http://poj.org/problem?id=1088 题目大意:给你一个m*n的矩阵 如果其中一个点高于另一个点 那么就可以从高点向下滑 直到没有可以下滑的时候 就得到一条下滑路径 求最大的下滑路径 分析:因为只能从高峰滑到低峰,无后效性,所以每个点都可以找到自己的最长下滑距离(只与自己高度有关).记忆每个点的最长下滑距离,当有另一个点的下滑路径遇到这个点的时候,直接加上这个点的最长下滑距离. dp递推式是,dp[x][y] = max(dp[x][y],dp[x+1][y]+

POJ 1385 计算几何 多边形重心

链接: http://poj.org/problem?id=1385 题意: 给你一个多边形,求它的重心 题解: 模板题,但是不知道为啥我的结果输出的确是-0.00 -0.00 所以我又写了个 if (ans.x == 0) ans.x = 0 感觉好傻逼 代码: 1 #include <map> 2 #include <set> 3 #include <cmath> 4 #include <queue> 5 #include <stack> 6