为了能到远方,脚下的每一步都不能|

园龄:粉丝:关注:

P4358 [CQOI2016] 密钥破解

显然只需要对 N 进行质因数分解即可求出 r,d
那么我们只需要用Pollard-Rho算法即可
然而发现不会写

#include<bits/stdc++.h>
using namespace std;
#define int __int128
int read(){
    int num=0,flag=1;char c;
    while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;
    while(c>='0'&&c<='9')num=(num<<3)+(num<<1)+(c^48),c=getchar();
    return num*flag;
}
void write(int x){
	if(x>=10)write(x/10);
	putchar(x%10+'0');
}
int abs(int x){
	return x>0?x:-x;
}
int f(int x,int c,int mod){
	return (x*x%mod+c)%mod;
}
int gcd(int a,int b){
	return b?gcd(b,a%b):a;
}
int ksm(int a,int b,int mod){
	int res=1;
	while(b>0){
		if(b&1)res=res*a%mod;
		a=a*a%mod;
		b>>=1;
	}
	return res;
}
bool mr(int x,int b){
	int k=x-1;
	while(k>0){
		int cur=ksm(b,k,x);
		if(cur^1 && cur^x-1)return 0;
		if((k&1)==1 || cur==x-1)return 1;
		k>>=1;
	}
	return 1;
}
bool prime(int x){
	if(x==46856248255981ll || x<2)return 0;
	if(x==2 || x==3 || x==7 || x==61 || x==24251)return 1;
	return mr(x,2) && mr(x,61);
}
int pollard_rho(int x){
	int s=0,t=0,c=1ll*rand()%(x-1)+1,val=1;
	for(int i=1;;i<<=1,s=t,val=1){
		for(int j=1;j<=i;j++){
			t=f(t,c,x);
			val=val*abs(t-s)%x;
			if(j%127==0){
				int d=gcd(val,x);
				if(d>1) return d;
			}
		}
		int d=gcd(val,x);
		if(d>1) return d;
	}
}
int e,n,c;
int p,q,r;
int x,y;
void exgcd(int a,int b){
    if(!b) x=1,y=0;
    else{
        exgcd(b,a%b);
        int k=x; x=y;
    	y=k-a/b*y;
    }
}
signed main(){
	e=read();n=read();c=read();
	p=n;
	while(p>=n)p=pollard_rho(n);
	q=n/p;
	r=(p-1)*(q-1);
	exgcd(e,r);x=(x%r+r)%r;
	write(x);putchar(' ');write(ksm(c,x,n));putchar('\n');
	return 0;
}

(逆元别用费马小定理,我调了半天)
感觉这题有点板子

本文作者:kent

本文链接:https://www.cnblogs.com/kentsbk/p/17651508.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Kent530  阅读(55)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起