AcWing 878. 线性同余方程

AcWing 878. 线性同余方程

一、题目描述

给定 n 组数据 ai,bi,mi,对于每组数求出一个 xi,使其满足 ai×xibi(mod mi),如果无解则输出 impossible

输入格式
第一行包含整数 n

接下来 n 行,每行包含一组数据 ai,bi,mi

输出格式
输出共 n 行,每组数据输出一个整数表示一个满足条件的 xi,如果无解则输出 impossible

每组数据结果占一行,结果可能不唯一,输出任意一个满足条件的结果均可。

输出答案必须在 int 范围之内。

数据范围
1n105,1ai,bi,mi2×109

输入样例:

2
2 3 6
4 3 5

输出样例:

impossible
-3

二、线性同余方程

【扩展欧几里得算法的一个典型应用】

ax b(mod m)

举个栗子
2x3(mod 6)


x=1,2x=2,2%6=2
x=2,2x=4,4%6=4
x=3,2x=6,6%6=0


x=4,2x=8,8%6=2
x=5,2x=10,10%6=4
x=6,2x=12,12%6=0


...
余数开始循环了,一直都是2,4,0...

不会产生3这个余数,所以,无解。

再来一个栗子:

4x 3(mod 5)

x=1,4x=4,4%5=4
x=2,4x=8,8%5=3
x=3,4x=12,12%5=2
x=4,4x=16,16%5=1
x=5,4x=20,20%5=0


x=6,4x=24,24%5=4
x=7,4x=28,28%5=3
x=8,4x=32,32%5=2
x=9,4x=36,36%5=1
x=10,4x=40,40%5=0


....
所以有解,其它第一个解是 x=2,第二个解是7
这两个解之间差了一个5,即2+5=7,每加一个5,都可以得到一个解。比如 7+5=12也是一个解。

2、为什么线性同余方程可以使用欧几里得算法来求解呢?

  • axb(mod m) 表示意义(ax)%m=b,从而(axb)%m=0

假设是y1倍,因此线性同余方程转化为 axb=my1 , 移项: axmy1=b。令 y1=y ,则: ax+my=b ,这就是一个标准的二元一次方程。

  • 根据贝祖定理,上述等式有解当且仅当 gcd(a,m)|b,也就是bgcd(a,m)的整数倍,有解;
    如果b不是gcd(a,m)的整数倍,无解,输出 impossible

  • 用扩展欧几里得求出一组特解 x0,y0, 使得 ax0+my0=gcd(a,m)

  • 对比两个方程:扩展欧几里得公式和线性同余方程两个东东

{ax+my=bax0+my0=gcd(a,m)

两个方程的左右两边,左边的系数是一样的a,m,右边的常数不一样,一个是b,另一个是gcd(a,m),我们刚才上面讨论过,b必须是gcd(a,m)的整数倍,方程才有解,也就是说,现在b一定是gcd(a,m)的整数倍!

d=gcd(a,m),那么b=td,其中t=b/gcd(a,m)是一个整数。

x=b/gcd(a,m)x0,

因为害怕在乘法运算过程中,造成爆int,所以,出发前对b进行了转long long操作,以保证不爆int.同时,因为是同余方程,如果取得的值大于m,还需要模一下m.即:

(LL) b / d * x % m

三、实现代码

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;

int exgcd(int a, int b, int &x, int &y) {
    if (!b) {
        x = 1, y = 0;
        return a;
    }
    int d = exgcd(b, a % b, y, x);
    y -= a / b * x;
    return d;
}

int main() {
    int n;
    cin >> n;
    while (n--) {
        int a, b, m;
        cin >> a >> b >> m;

        int x, y;
        int d = exgcd(a, m, x, y);
        if (b % d)
            puts("impossible");
        else
            printf("%d\n", (LL)b / d * x % m);
    }
    return 0;
}

posted @   糖豆爸爸  阅读(374)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
历史上的今天:
2019-10-07 课堂上用人脸识别“记录分析”学生表情?我反对!
2019-10-07 jetbreains的crack方法
2015-10-07 现行开发模块测试地址
Live2D
点击右上角即可分享
微信分享提示