P2613 【模板】有理数取余 解题报告

P2613 【模板】有理数取余 解题报告

模版题

1. 原题 P2613 【模板】有理数取余

2. 概述题意

\(\quad\)给定一个有理数(以分数形式给出),给定a,b(a为分子,b为分母),求出这个有理数 \(\frac{a}{b}\ mod\ 19260817\)后的值

也就是求解 \(x \equiv \frac{a}{b} \pmod{19260817}\) 这个方程的 最小整数解

3. 简化题意

\(\quad\)首先题目中的:“这个值被定义为 \(bx \equiv a \pmod{19260817}\) 的解。”
是怎么来的呢?

这其实出自一个性质:

同乘性:若 $ a \equiv b \pmod{p} $,则 $ a * c \equiv b * c \pmod{p}$

我们将 \(x \equiv \frac{a}{b} \pmod{19260817}\) 这个方程左右两边同乘 \(b\) 可以得到 \(x\ \cdot \ b \equiv \frac{a}{b} \ \cdot \ b \pmod{19260817}\) 这个方程也就是 \(bx \equiv a \pmod{19260817}\)

很好,那么目前的题目就是要 求解 \(bx \equiv a \pmod{19260817}\) 的最小整数解

4. 求解

\(\quad\)停停停,先不要对着这个柿子发呆,有没有感觉他长得有点像一个东西:

乘法逆元:若 \(a x \equiv 1 \pmod{p}\) 则称 \(x\) 为 \(a\) 在模 \(p\) 意义下的乘法逆元,记作 \(a^{-1}\)

如果不知道什么是乘法逆元,点这里

如果我们可以求解出 \(bx_0 \equiv 1 \pmod{19260817}\) 的解,那我们是不是可以通过左右同乘 \(a\) 来得到 \(bx \equiv a \pmod{19260817}\) 的解呢?

具体操作如下:

\[b \ x_0 \equiv 1 \pmod{19260817} \implies b \ x_0 \ a \equiv 1 \cdot a \pmod{19260817} \]

\[b \cdot (a \cdot x_0) \equiv a \pmod{19260817} \]

所以 \(bx \equiv a \pmod{19260817}\) 的解就是:

\[x = (a \cdot x_0) \]

如果不知道如何求 \(bx \equiv 1 \pmod{p}\) 的解,可以先去做 P1082 同余方程

题目似乎说了还有无解情况?

如果 \(b\) 是 \(19260817\) 的倍数,那么此时,如果 \(a\) 也是 \(19260817\) 的倍数那么上述方程恒成立,无数解,如果 \(a\) 不是 \(19260817\) 的倍数,那么上述方程一定无解

所以当 b % 19260817 == 0 时无解

题目中的a,b似乎很大?难道高精度? 没必要:

\[b \ x \equiv a \pmod{19260817} \implies (b \ mod \ 19260817 ) \ x \equiv a\ mod \ 19260817 \pmod{19260817} \]

所以我们可以在开始的时候读入字符串,再将字符转化为数字,转化的时候再模一下这样就不会爆了

5. 总结

  • 读入a,b字符串并在读入后一位一位转化a,b为数字,转化时边模边转

  • 判断 b % 19260817 == 0 如果是,则无解 puts("Angry!")

  • 求解方程 \(bx_0 \equiv 1 \pmod{19260817}\) 的解 \(x_0\)

  • 输出 \(bx \equiv a \pmod{19260817}\) 的解 \(x = x_0 \ \cdot \ a\)

6. 参考代码

我这里用的是快速幂求解逆元

#include<bits/stdc++.h>
#define int long long

using namespace std;

typedef long long LL;
typedef pair<int, int> PII;
const int N = 1e6 + 10, mod = 19260817;

int get(string s){
    int n = s.size();
    s = ' ' + s;

    int res = 0;
    for(int i = 1 ; i <= n ; i ++){
        res = res * 10 + (s[i] - '0');
        res %= mod;
    }
    return res;
}

int qmi(int a, int k, int mod){
    int res = 1;
    while(k){
        if(k & 1) res = res * a % mod;
        k >>= 1;
        a = a * a % mod;
    }
    return res;
}

signed main(){
    
    string a, b;
    cin>>a>>b;

    int x = get(a), y = get(b);

    // cout<<x<<' '<<y<<'\n';
    if(y % mod == 0) return 0 * puts("Angry!");

    int ans = qmi(y, mod - 2, mod) * x % mod;
    cout<<ans;

    return 0;
}

完结撒花 ✿✿ヽ(°▽°)ノ✿

posted @ 2026-04-21 15:47  神烦doge  阅读(25)  评论(0)    收藏  举报