洛谷题单指南-进阶数论-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;
}
浙公网安备 33010602011771号