洛谷题单指南-进阶数论-P2613 【模板】有理数取余

原题链接:https://www.luogu.com.cn/problem/P2613

题意解读:求(a / b) % 19260817 , a, b是大数,会超出long long范围。

解题思路:

(a / b) % 19260817 即a * b-1 % 19260817

b-1表示b模19260817的逆元,可以基于扩展欧几里得算法来求bx+19260817y = 1的最小正整数解

由于b较大,上式也可以写作(b%19260817+19260817k)x+19260817y = 1,

y是任意整数,本质上就是(b%19260817)x+19260817y =1 ,将b直接取模缩小处理, b = b % 19260817

而对于a,根据取模乘法性质,可以先将a = a % 19260817

对于无解的情况,只要判定gcd( b % 19260817, 19260817) != 1则无解

100分代码:

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

const int MOD = 19260817;
string A, B;

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

int main()
{
    cin >> A >> B;
    int a = 0, b = 0;

    // a = A % MOD
    for(int i = 0; i < A.size(); i++)
    {
        a = 10 * a + A[i] - '0';
        a %= MOD;
    }

    // b = B % MOD
    for(int i = 0; i < B.size(); i++)
    {
        b = 10 * b + B[i] - '0';
        b %= MOD;
    }

    int x, y;
    int d = exgcd(b, MOD, x, y);
    if(d != 1) cout << "Angry!";
    else 
    {
        x = (x % MOD + MOD) % MOD;
        cout << 1ll * a * x % MOD;
    }
    return 0;
}

 

posted @ 2025-10-15 11:30  hackerchef  阅读(6)  评论(0)    收藏  举报