loj6392 「THUPC2018」密码学第三次小作业 / Rsa

还是挺好做的,((e_1,e_2)=1 Rightarrow e_1s+e_2t=0)(m equiv m^1 equiv m^{e_1s+e_2t} equiv c_1^s c_2^t)。exgcd求逆元

#include <iostream>
#include <cstdio>
using namespace std;
typedef long long ll;
int T;
ll exgcd(ll a, ll b, ll &x, ll &y){
	if(!b){
		x = 1;
		y = 0;
		return a;
	}
	ll gcd=exgcd(b, a%b, x, y);
	ll z=x;
	x = y;
	y = z - (a / b) * y;
	return gcd;
}
ll mul(ll a, ll b, ll p){
	ll re=0;
	while(b){
		if(b&1)	re = (re + a) % p;
		a = (a + a) % p;
		b >>= 1;
	}
	return re;
}
ll ksm(ll a, ll b, ll p){
	ll re=1;
	while(b){
		if(b&1)	re = mul(re, a, p);
		a = mul(a, a, p);
		b >>= 1;
	}
	return re;
}
int main(){
	cin>>T;
	while(T--){
		ll c1, c2, e1, e2, s, t, x, y, n;
		scanf("%lld %lld %lld %lld %lld", &c1, &c2, &e1, &e2, &n);
		exgcd(e1, e2, s, t);
		if(t>0){
			ll tmp=t/e1;
			s += tmp * e2; t -= tmp * e1;
			if(t>0){
				s += e2;
				t -= e1;
			}
		}
		exgcd(c2, n, x, y);
		x = (x % n + n) % n;
		t *= -1;
		printf("%lld
", mul(ksm(c1,s,n),ksm(x,t,n),n));
	}
	return 0;
}
原文地址:https://www.cnblogs.com/poorpool/p/9075838.html