转化为e_gcd(1576)

本文详细解释了如何使用扩展欧几里得算法解决9973模下的乘法逆元问题,并通过实例展示了计算过程。文章深入探讨了数学原理与应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

A/B

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3707    Accepted Submission(s): 2835


Problem Description
要求(A/B)%9973,但由于A很大,我们只给出n(n=A%9973)(我们给定的A必能被B整除,且gcd(B,9973) = 1)。
 

Input
数据的第一行是一个T,表示有T组数据。
每组数据有两个数n(0 <= n < 9973)和B(1 <= B <= 10^9)。
 

Output
对应每组数据输出(A/B)%9973。
 

Sample Input
2 1000 53 87 123456789
 

Sample Output
7922 6060

原题要求(A/B)%9973且n=A%9973 -->Bx=A --> Bx=n (mod 9973) --> Bx+9973y=n 求解x在(0,9973)的最小整数解,所以这就化成了一个标准的扩展欧几里德算法的乘法逆元。原题还有条件:gcd(B,9973)=1。所以此不定方程必有解。


/*------------------Header Files------------------*/
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <ctype.h>
#include <cmath>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <vector>
#include <set>
#include <limits.h>
using namespace std;
/*------------------Definitions-------------------*/
#define LL long long
#define uLL unsigned long long
#define PI acos(-1.0)
#define INF 0x3F3F3F3F
#define MOD 9973
#define MAX 100050
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
/*---------------------Work-----------------------*/
LL e_gcd(LL a,LL b,LL &x,LL &y)
{
	if(b==0)
	{
		x=1,y=0;
		return a;
	}
	LL ans=e_gcd(b,a%b,x,y);
	LL temp=x;
	x=y;
	y=temp-a/b*y;
	return ans;
}
LL cal(LL a,LL b,LL c)
{
	LL x,y;
	LL gcd=e_gcd(a,b,x,y);
	if(c%gcd!=0) return -1;
	x*=c/gcd;
	b/=gcd;
	if(b<0) b=-b;
	LL ans=x%b;
	if(ans<=0) ans+=b;
	return ans;
}
void work()
{
	int T; cin>>T;
	while(T--)
	{
		int n;
		LL b;
		scanf("%d%I64d",&n,&b);
		printf("%I64d\n",cal(b,9973,n));
	}
}
/*------------------Main Function------------------*/
int main()
{
	//freopen("test.txt","r",stdin);
	work();
	return 0;
}



RSA密码系统 是最常用的非对称密钥密码术之一,其安全性基于大整数质因子分解问题的困难性,即给定一个大整数,在短时间内将其分解为多个质因数的乘积在计算上是极其困难的。 在一个完整的通信过程中,其工作流程大致为: 接收者生成两个 大质数 � , � p,q,计算 � � � N=pq,同时生成公钥 � � � � { � , � } k pub ​ ={e,N} 与私钥 � � � � { � , � } k pri ​ ={d,N}。 接收者广播公钥 � � � � { � , � } k pub ​ ={e,N}。 发送者使用公钥加密数据,得到密文 � � ( � � � � , � ) � � m o d     � c=f(k pub ​ ,m)=m e modN。 发送者广播密文 � c。 接收者使用私钥解密数据,得到明文 � � ( � � � � , � ) � � m o d     � m=g(k pri ​ ,c)=c d modN。 其中的值满足以下性质: � < � m<N, gcd( � , � ) 1 gcd(m,N)=1. � < � e<N, gcd( � , � ) 1 gcd(e,N)=1. � � ≡ 1 ( m o d     � () ) ed≡1(modφ(N)). � () ( � − 1 ) ( � − 1 ) φ(N)=(p−1)(q−1). 如果明文 � m 规模过大,可考虑将其分段发送。 现有某道 CTF 题目涉及此过程,而不幸的是你正好是 隔壁老王 题目涉及通信过程中的“非法第三者”。你希望获取通信内容 � m,但现在你只知道 � , � , � e,N,c 的值与关于 � , � p,q 的一个性质: ∣ � − � ∣ ≤ 2 × 1 0 5 ∣p−q∣≤2×10 5 。 希望你能根据以上信息与给定的 � , � , � e,N,c 快速求出明文 � m。 输入:一行 3 3 个整数,分别为 � , � , � e,N,c 的值。 输出:一行 1 1 个整数, � m 的值。 样例输入:65537 293000179499792623 13189131411060906 样例输出:114514 数据范围: 1≤N≤10 18 。 1 ≤ � ≤ � , gcd( � , � ) 1 1≤e≤N,gcd(e,N)=1。 0 ≤ � < � 0≤C<N。 � � � N=pq,其中 � , � p,q 为质数,且 ∣ � − � ∣ ≤ 2 × 1 0 5 ∣p−q∣≤2×10 5 。 此外:你可能需要使用 扩展欧几里得算法 的相关结论在已知 � , � () e,φ(N) 的情况下求 � d,下面将提供相关代码,求 � d 时调用 d=mod_inverse(e,phi) 即可,其两个参数分别为 � e 与 � () φ(N) 的值。 long long extended_gcd(long long a, long long b, long long *x, long long *y) { if (a == 0) { *x = 0; *y = 1; return b; } long long x1, y1, gcd = extended_gcd(b % a, a, &x1, &y1); *x = y1 - (b / a) * x1; *y = x1; return gcd; } long long mod_inverse(long long e,long long phi) { long long x, y, gcd = extended_gcd(e, phi, &x, &y); if (gcd != 1)return -1;//表示错误,但本题数据保证不会有此情况 else { x = (x % phi + phi) % phi; return x; } } 你可能需要使用 快速幂算法 以高效地由 � , � , � c,d,N 求出 � m,下面将提供相关代码。 long long qmi(long long c,long long d,long long N){ long long res=1%N; while(d){ if(d&1)res=(__int128)res*c%N; c=(__int128)c*c%N; d>>=1; } return res; } 上述第二段代码中使用了数据类型 __int128,其是128位整型。截至2024年底,__int128 不是C/C++中的标准数据类型。但包括本平台在内的大多数编译器支持该类型。如编译器不支持,另可使用 龟速乘算法 替代,其在理论上其对本处的程序运行效率几乎没有影响。
03-23
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值