hdu 1211 逆元

RSA

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 2353    Accepted Submission(s): 1677

Problem Description

RSA is one of the most powerful methods to encrypt data. The RSA algorithm is described as follow:

> choose two large prime integer p, q
> calculate n = p × q, calculate F(n) = (p - 1) × (q - 1)
> choose an integer e(1 < e < F(n)), making gcd(e, F(n)) = 1, e will be the public key
> calculate d, making d × e mod F(n) = 1 mod F(n), and d will be the private key

You can encrypt data with this method :

C = E(m) = me mod n

When you want to decrypt data, use this method :

M = D(c) = cd mod n

Here, c is an integer ASCII value of a letter of cryptograph and m is an integer ASCII value of a letter of plain text.

Now given p, q, e and some cryptograph, your task is to "translate" the cryptograph into plain text.

Input

Each
case will begin with four integers p, q, e, l followed by a line of
cryptograph. The integers p, q, e, l will be in the range of 32-bit
integer. The cryptograph consists of l integers separated by blanks.

Output

For
each case, output the plain text in a single line. You may assume that
the correct result of plain text are visual ASCII letters, you should
output them as visualable letters with no blank between them.

Sample Input

101 103 7 11
7716 7746 7497 126 8486 4708 7746 623 7298 7357 3239

Sample Output

I-LOVE-ACM.

Author

JGShining(极光炫影)

Source

杭电ACM省赛集训队选拔赛之热身赛

解密方式 M=c^d mod n

c就是题目中给的数字,n=p*q,现在关键是求d,由  d*e≡1 (mod fn)  fn=(p-1)*(q-1),gcd(e,fn)=1,易得d=e-1,只要求出e  mod fn的逆元即可。

此逆元不能取模fn又很大,所以费马小定理不是很实用,这里采用拓展欧几里得求逆元。

#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define lld long long
void exGcd (lld a, lld b, lld &d, lld &x, lld &y)
{
    if (b == 0)
    {
        x = 1 ;
        y = 0 ;
        d = a ;
        return ;
    }
    exGcd (b, a%b, d, x, y) ;
    lld tmp = x ;
    x = y ;
    y = tmp - a/b*y ;
}
LL qpow(LL a,LL b,LL c)
{
    LL r=1;
    while(b){
        if(b&1) r=r*a%c;
        a=a*a%c;
        b>>=1;
    }
    return r;
}
int main()
{
    LL p,q,e,n,fn,l;
    lld d,x,y;
    while(cin>>p>>q>>e>>l){n=p*q;
            fn=(p-1)*(q-1);
            exGcd(e,fn,d,x,y);
            x=(x%fn+fn)%fn;
        for(int i=1;i<=l;++i){
            LL num;
            scanf("%lld",&num);
            printf("%c",qpow(num,x,n));
        }cout<<endl;
    }
    return 0;
}

时间: 2024-10-05 05:50:21

hdu 1211 逆元的相关文章

hdu 1211

这题就是 要你找出一个ASCII 的值x使得  :  x^e%n==num(当前输入的数,e条件已给出) zsd: 1: ASCII0-255可以枚举 2:   =a^11   11=1011 ? 1 2 3 4 5 6 7 8 9 10 11 12 int pow2( int a, int b ) {     int r = 1, base = a;     while( b != 0 )     {         if( b % 2 )             r *= base;    

POJ 2478 欧拉函数(欧拉筛法) HDU 1576 逆元求法

相关逆元求法,我之前有写过,还有欧拉函数的求法,欧拉函数与逆元的关系  点击 POJ 2478 又是一个打表的题目,一眼看出结果就是前n个欧拉函数值的和. 这里直接计算欧拉函数值求和会超时,看见多组数据. 然后就是计算欧拉函数,打表就好了. #include <stdio.h> #include <string.h> #include <iostream> using namespace std; typedef long long LL; const int N =

hdu 5685(逆元)

Problem A Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 520    Accepted Submission(s): 203 Problem Description 度熊手上有一本字典存储了大量的单词,有一次,他把所有单词组成了一个很长很长的字符串.现在麻烦来了,他忘记了原来的字符串都是什么,神奇的是他竟然记得原来那些字符串的

HDU 4828 逆元+catalan数

Grids Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Submission(s): 953    Accepted Submission(s): 418 Problem Description 度度熊最近很喜欢玩游戏.这一天他在纸上画了一个2行N列的长方形格子.他想把1到2N这些数依次放进去,但是为了使格子看起来优美,他想找到使每行每列都递增的方案.不过画了很

HDU 5651 逆元

xiaoxin juju needs help Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 809    Accepted Submission(s): 231 Problem Description As we all known, xiaoxin is a brilliant coder. He knew **palindromi

HDU 1211: RSA

RSA ///@author Sycamore, ZJNU; ///@date 8/4/2017 #include<iostream> using namespace std; typedef long long ll; ll mod(ll a, ll b) { return ((a%b) + b) % b; } ll extended_euclid(ll a, ll b, ll &x, ll &y) { ll xx = y = 0; ll yy = x = 1; while 

数论(一)

HDU 2669 ex_GCD HDU 1576 逆元,ex_GCD HDU 4828 卡特兰数 假设,依次放1-n,放第一排记为0,放第二排记为1,题目的条件就转化为卡特兰数的条件了 附:线性求逆元,卡特兰数(递推) p[1] = 1; for (int i = 2; i < 1000003; i++) { p[i] = - (MODP / i) * p[MODP % i]; p[i] = (p[i] % MODP + MODP) % MODP; } f[1] = 1; for (int i

hdu NPY and girls 莫队+逆元

NPY and girls Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Problem Description NPY's girlfriend blew him out!His honey doesn't love him any more!However, he has so many girlfriend candidates.Because there are to

HDU 5976 数学,逆元

1.HDU 5976 Detachment 2.题意:给一个正整数x,把x拆分成多个正整数的和,这些数不能有重复,要使这些数的积尽可能的大,输出积. 3.总结:首先我们要把数拆得尽可能小,这样积才会更大(当然不能拆1).所以容易想到是拆成2+3+...+n+s=x,先求出n即2+3+...+n<x<2+3+...+n+(n+1),然后将某个数向右平移s个单位变为n+1即可.注意:(1)预处理出前缀和,前缀积.(2)将某个数移到n+1,要除这个数再乘n+1,这里要用逆元,也要预处理出来. #in