BZOJ 4522: [Cqoi2016]密鑰破解

數論模板大整合。。。。。。

快速乘+快速冪+擴展gcd+Pollard_Rho

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
#include<queue>
#include<vector>
#include<algorithm>
#include<map>
#include<set>
#define rep(i,l,r) for(int i=l;i<=r;i++)
#define per(i,r,l) for(int i=r;i>=l;i--)
#define mmt(a,v) memset(a,v,sizeof(a))
#define tra(i,u) for(int i=head[u];i;i=e[i].next)
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll iabs(ll x){return x<0?-x:x;}
ll qmul(ll a,ll b,ll p){
	ll ans=0;
	for(;b;b>>=1,a=(a<<1)%p)if(b&1)ans=(ans+a)%p;
	return ans;
}
ll qpow(ll a,ll b,ll p){
	ll ans=1;
	for(;b;b>>=1,a=qmul(a,a,p))if(b&1)ans=qmul(ans,a,p);
	return ans;
}
ll Pollard_Rho(ll n,ll c){
	while(true){
		ll x,y,d,i=1,k=2;
		x=y=rand()%(n-1)+1;
		while(true){
			i++;
			x=(qmul(x,x,n)+c)%n;
			if(x==y)break;
			d=gcd(iabs(y-x),n);
			if(d!=1&&d!=n)return d;
			if(i==k)y=x,k<<=1;
		}
		c--;
	}
}
ll exgcd(ll a,ll b,ll &x,ll &y,ll &d){
	if(b){exgcd(b,a%b,y,x,d);y-=x*(a/b);}
	else{x=1,y=0;d=a;}
}
ll inv(ll x,ll p){
	ll a,b,c;
	exgcd(x,p,a,b,c);
	return (a+p)%p;
}
int main(){
	//freopen("a.in","r",stdin);
	srand(199941213);
	ll e,n,c;scanf("%lld%lld%lld",&e,&n,&c);
	ll p=Pollard_Rho(n,16381),q=n/p,r=(p-1)*(q-1);
	ll d=inv(e,r);
	printf("%lld %lld\n",d,qpow(c,d,n));
	return 0;
}


發佈了293 篇原創文章 · 獲贊 3 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章