1 条题解
-
0
自动搬运
来自洛谷,原作者为

Aw顿顿
直须看尽洛城花,始共春风容易别搬运于
2025-08-24 22:10:53,当前版本为作者最后更新于2021-07-11 10:07:58,作者可能在搬运后再次修改,您可在原文处查看最新版自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多
以下是正文
题意概括
实际上,题目背景和所求并没有很强的相关性,现摘录简化版题目要求:
现有相同的模数 与不同的私钥。设两公钥分别为 且 。明文消息为 ,密文分别为:
$$\begin{matrix}c_1=m^{e_1}\bmod N\\c_2=m^{e_2}\bmod N\end{matrix} $$已知 ,求 。
寻找突破口
重点应该在 互质,也就是说 ,这是突破口。
于是我们可以发现应当有整数 使得下列式子成立:
我们发现,式子的右边是 ,这个 必须成为连接答案和题设的桥梁。如何让这个 把两者连接起来呢?一个比较朴素的想法是将 与 相乘,但是这是徒劳的。
推导式子
我们会发现,在题目所给的式子中:
$$\begin{matrix}c_1=m^{e_1}\bmod N\\c_2=m^{e_2}\bmod N\end{matrix} $$
都是以指数的形态出现,也就是说如果我们能够把 作为指数和这个式子放在一起,可能会有转机。那么我们试着在模 意义下处理:
$$m\equiv m^1\equiv m^{s\cdot e_1+t\cdot e_2}\pmod N $$如果我们利用幂的性质,将指数上不大好处理的 变成乘号,就能够得到一个式子:
$$m\equiv m^{s\cdot e_1}\times m^{t\cdot e_2}\pmod N $$这时候我们注意到一件事情,在式子中独立出现了 和 ,回归到题目所给的式子:
$$\begin{matrix}c_1=m^{e_1}\bmod N\\c_2=m^{e_2}\bmod N\end{matrix} $$
我们会发现这里实际上可以进行一个替换,也就是说我们可以在模 的意义下把 和 用 和 替换,得到了一个式子如下: :
求解方法
对于题解开头的那个式子,我们可以很轻松地使用 求得 的值,而现在的问题仅仅存在于答案的计算。我们很自然的会想到这是一个使用快速幂的好机会,但是我们不能想到一件事:如果 怎么办?
其实还真的不难处理,我们只需要将 就行了,如果把它放在原来的式子当中(在模 意义下讨论),就可以得到 。此时后半部分由于 是负数,指数就是正数可以用快速幂计算,而前半部分只要在模 意义下求取逆元即可,但是因为不可抗力不能使用 Fermat Little Theorem,于是你可以使用 Exgcd 求解。
记得要开
long long,并且有些点爆了还得单独特殊处理,由于处理不善,所以龟速乘部分采自神 GoPoux4 的代码,其余部分按照文章推导进行处理即可,具体见代码。代码实现
#include<bits/stdc++.h> #define int long long using namespace std; int c1,c2,e1,e2,N,T; int gsc(int a,int b){ int ans=0; while(b>0){ if(b&1) ans=(ans+a)%N; a=(a+a)%N; b>>=1; }return ans; }int ksm(int a,int b){ int ans=1; a%=N; while(b>0){ if(b&1)ans=gsc(ans,a); a=gsc(a,a); b>>=1; }return ans%N; }int exgcd(int a,int b,int &x,int &y){ if(!b) {x=1,y=0;return a;} int k=exgcd(b,a%b,x,y); int z=x;x=y,y=z-a/b*y; return k; }int inv(int a,int b){ int x,y; int g=exgcd(a,b,x,y); return g==1?(x%b+b)%b:-1; }signed main(){ cin>>T; while(T--){ cin>>c1>>c2>>e1>>e2>>N; int s,t,g=exgcd(e1,e2,s,t); if(s<0)c1=inv(c1,N),s=-s; if(t<0)c2=inv(c2,N),t=-t; cout<<gsc(ksm(c1,s),ksm(c2,t))<<endl; }return 0; }
- 1
信息
- ID
- 4440
- 时间
- 1000ms
- 内存
- 500MiB
- 难度
- 5
- 标签
- 递交数
- 0
- 已通过
- 0
- 上传者