P4358 [CQOI2016] 密钥破解
显然只需要对
那么我们只需要用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 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步