同余方程、乘法逆元

题目链接

P1082 [NOIP2012 提高组] 同余方程

P2613 【模板】有理数取余


P1082 [NOIP2012 提高组] 同余方程

题目描述

求关于x的同余方程 ax1(modb) 的最小正整数解。

输入格式

一行,包含两个正整数 a,b,用一个空格隔开。

输出格式

一个正整数 x0 ,即最小正整数解。输入数据保证一定有解。

输入

3 10

输出

7

说明/提示

【数据范围】

对于 40%的数据,2b1,000

对于 60%的数据,2b50,000,000

对于 100%的数据,2a,b2,000,000,000

解题思路

线性同余方程:给定整数 a,b,m, 求一个整数 x 满足 a×xb(modm),或者给出无解。

a×xb(modm)a×xbmya×x+m×y=b

此时将问题转化成了扩展欧几里得算法
有解时,求出一组整数 x0,y0,满足 a×x0+m×y0=gcd(a,m),则通解:

x=x0×bgcd(a,m)+k×mgcd(a,m)

代码

  • 时间复杂度:O(log(a+b))
#include<bits/stdc++.h> using namespace std; using LL=long long; LL a,b; LL exgcd(LL a,LL b,LL &x,LL &y) { if(b==0) { x=1,y=0; return a; } LL d=exgcd(b,a%b,x,y); LL z=x; x=y,y=z-y*(a/b); return d; } int main() { scanf("%lld%lld",&a,&b); LL x,y; exgcd(a,b,x,y); printf("%lld",(x+b)%b); return 0; }

P2613 【模板】有理数取余

题目描述

给出一个有理数 c=ab ,求 cmod19260817 的值。

输入格式

一共两行。

第一行,一个整数 a
第二行,一个整数 b

输出格式

一个整数,代表求余后的结果。如果无解,输出 Angry!

输入

233 666

输出

18595654

说明/提示

对于所有数据,保证 0a10100011b1010001 ,且 a,b 不同时是 19260817 的倍数。

解题思路

同余方程

求解 abmodp 等价于求解 xab(modp)xmodp,而:

xab(modp)bxa(modp)

即求解同余方程~
至于大数,将大整数根据秦九韶公式写成“自左向右”,取模即可~

  • 时间复杂度:O(log(19260817+b))

乘法逆元

显然,19260817 是质数,与 b 互质时(即 b0 )可直接通过乘法逆元求解

  • 时间复杂度:O(log(19260815))

代码

  • 同余方程
#include<bits/stdc++.h> using namespace std; using LL=long long; const LL mod=19260817; string a,b; LL A,B; LL exgcd(LL a,LL b,LL &x,LL &y) { if(b==0) { x=1,y=0; return a; } LL d=exgcd(b,a%b,x,y); LL z=x; x=y,y=z-y*(a/b); return d; } int main() { cin>>a>>b; for(int i=0;i<a.size();i++) A=(A*10+a[i]-'0')%mod; for(int i=0;i<b.size();i++) B=(B*10+b[i]-'0')%mod; LL x,y; LL d=exgcd(B,mod,x,y); if(A%d)puts("Angry!"); else printf("%lld",(x*A/d%mod+mod)%mod); return 0; }
  • 乘法逆元
#include<bits/stdc++.h> using namespace std; using LL=long long; const LL mod=19260817; string a,b; LL A,B; LL ksm(LL a,LL b) { LL res=1%mod; for(;b;b>>=1) { if(b&1)res=res*a%mod; a=a*a%mod; } return res; } int main() { cin>>a>>b; for(int i=0;i<a.size();i++) A=(A*10+a[i]-'0')%mod; for(int i=0;i<b.size();i++) B=(B*10+b[i]-'0')%mod; if(!B)puts("Angry!"); else printf("%lld",(A*ksm(B,mod-2)+mod)%mod); return 0; }

__EOF__

本文作者acwing_zyy
本文链接https://www.cnblogs.com/zyyun/p/15316975.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   zyy2001  阅读(103)  评论(0编辑  收藏  举报
编辑推荐:
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示