【2022杭电多校-2】1009 ShuanQ

97 阅读1分钟

本文已参与「新人创作礼」活动, 一起开启掘金创作之路。

题目链接

acm.hdu.edu.cn/contests/co…

HDU最近好像打不开了……

1009 ShuanQ

CX is a programmer of a mooc company. A few days ago, he took the blame for leakage of users' data. As a result, he has to develop an encryption algorithm, here is his genius idea.

First, the protocol specifies a prime modulus M, then the server generates a private key P, and sends the client a public key Q. Here Q=P−1,P×Q≡1modM.

Encryption formula: encrypted_data=raw_data×PmodM

Decryption formula: raw_data=encrypted_data×QmodM

It do make sense, however, as a master of number theory, you are going to decrypt it.You have intercepted information about P,Q,encrypted_data, and M keeps unknown. If you can decrypt it, output raw_data, else, say "shuanQ" to CX.

Input

First line has one integer T(T≤20), indicating there are T test cases. In each case:

One line has three integers P,Q,encrypteddataP,Q,encrypted_data. (1<P,Q,encrypteddata2×106)(1<P,Q,encrypted_{data}\le 2×10^6)

It's guaranteed that P,Q,encrypteddata<MP,Q,encrypted_{data}<M.

Output

In each case, print an integer rawdataraw_{data}, or a string "shuanQ".

Sample Input

2

5 5 5

6 6 6

Sample Output

shuanQ

1

题目大意

Q=P1,P×Q1modMQ = P ^ {-1},P \times Q \equiv 1 \mod M,

Q=P1Q=P−1

encrypteddata=rawdata×PmodMencrypted_{data} = raw_{data} \times P \mod M

rawdata=encrypteddata×QmodMraw_{data} = encrypted_{data} \times Q \mod M

多组数据,每组数据对于给定的 PPQQencrypteddataencrypted_{data} 含义见上文所述,输出对应的rawdataraw_{data},如果没有合法的解就输出“ShuanQ”。

思路

通过阅读题目我们可以轻松地得知结论 PQ=1(modM)P*Q=1(\mod M),变形这个式子,我们可以发现:

所以 PQkM=1P*Q-k*M=1

所以 M(PQ1)M|(P*Q-1),

又M是质数且比P、Q、enc大,

所以我们只需要将 PQ1P*Q-1 分解出质因子,再和 P,Q,encP,Q,enc 比较一下就结束了。

代码

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <queue>
using namespace std;
const int N=100001;
int T,n,k;
long long P,Q,m,qwq;
int solve()
{
        //读入 P、Q 和 encrypted_data
	scanf("%lld%lld%lld",&P,&Q,&m);
        //分解 P*Q-1 的质因数
	qwq=P*Q-1;
	for (long long i=2;i*i<=qwq;++i)
		while (qwq%i==0) qwq/=i;
	if (qwq>m&&qwq>P&&qwq>Q) printf("%lld\n",m*Q%qwq);
	else printf("shuanQ\n");
        return 0;
}
int main()
{
        //多组数据
        int T;
	for (scanf("%d ",&T);T--;) solve();
        return 0;
}