题意 : 给你n,e,c,并且知道me ≡ c (mod n),而且n = p*q,pq都为素数。
思路 : 这道题的确与题目名字很相符,是个RSA算法,目前地球上最重要的加密算法。RSA算法原理 。
看到这个算法之后,就知道这个题是求cd≡m(mod n),要求m,就要先求d,而d则是e的模反元素。
如果两个正整数a和n互质,那么一定可以找到整数b,使得 ab-1 被n整除,或者说ab被n除的余数是1。这时,b就叫做a的模反元素。
由模反元素可知,ed≡1(mod Phi[n])(phi[n]代表n的欧拉函数)。
根据欧拉函数性质可知,phi[n] = (p-1)*(q-1)。
求e的逆元d需要用扩展欧几里得,ed+k*phi[n]=1.要注意处理求出的d是负数的情况。
最后求cd就要用到快速幂模,然后再MOD n 就是所求m。
#include <stdio.h> #include <string.h> #include <iostream> typedef long long LL ; using namespace std ; bool isprime(int n) { for(int i = 2 ; i * i <= n ; i++) { if(n % i == 0) return false ; } return true ; } int multimod(int a,int n,int m) { int tmp = a , res = 1 ; while(n) { //printf("11\n") ; if(n & 1) { res *= tmp ; res %= m ; } tmp *= tmp ; tmp %= m ; n >>= 1 ; //printf("%d\n",n) ; } return res ; } void exde(int a,int b,int &x,int& y) { int t ; if(b == 0) { x = 1 ; y = 0 ; return ; //return a; } exde(b,a%b,x,y) ; t = x ; x = y ; y = t-(a/b)*y; //return d ; } int main() { int T ,e,c,n; scanf("%d",&T) ; while(T--) { scanf("%d %d %d",&e,&n,&c) ; int p,q ,x,y; //printf("1\n"); for(int i = 2 ; i * i <= n ; i++) { if((n % i == 0) && isprime(i) && isprime(n / i)) { p = i ; q = n / i ; break ; } } //printf("p = %d q = %d\n",p,q) ; exde(e,(p-1)*(q-1),x,y); //printf("%d %d\n",p,q) ; int d = x ; //printf("%d\n",d+(p-1)*(q-1)) ; if(d < 0) d = (d+(p-1)*(q-1)) %((p-1)*(q-1)) ; //printf("%d\n",d) ; int ans = multimod(c,d,n) ; printf("%d\n",ans) ; } return 0 ; }