题解 P2613 【模板】有理数取余
题意简述
求 \(\dfrac{a}{b} \bmod 19260817\) 的值。
\(0 \leq a \leq 10^{10001} ,1 \leq b \leq 10^{10001}\) 。
Solution
把式子转化一下,其实就是求一个整数 \(x\) ,使得 \(x\equiv \dfrac{a}{b} \pmod {19260817}\) 。
然后推一下式子:
\[x\equiv \dfrac{a}{b} \pmod {19260817} \\
x \times b \equiv \dfrac{a}{b} \times b \pmod {19260817} \\
bx \equiv a \pmod {19260817} \\
(b \bmod 19260817)x \equiv (a \bmod 19260817) \pmod {19260817}
\]
于是可以先让 \(a,b\) 在读入时取模,将 \(a,b\) 减到一个更小的范围。
设 \(bx' \equiv 1 \pmod {19260817}\) ,那么有:
\[abx'\equiv a \pmod {19260817} \\
b(ax') \equiv a \pmod {19260817}
\]
于是求出 \(bx'\equiv \pmod {19260817}\) 的一个解,然后把这个解乘上 \(a\) 即可。
至于怎么做嘛,可以用拓展欧几里得,也可以用费马小定理( \(19260817\) 是一个质数)。
这里用的是费马小定理,时间复杂度 \(\mathcal{O}(\log mod)\) 代码如下:
#include <cstdio>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <iostream>
#include <queue>
typedef long long LL;
using namespace std;
const int mod = 19260817;
inline int read() {
int num = 0 ,f = 1; char c = getchar();
while (!isdigit(c)) f = c == '-' ? -1 : f ,c = getchar();
while (isdigit(c)) num = ((num << 1) + (num << 3) + (c ^ 48)) % mod ,c = getchar();
return num * f;
}
inline int pow(int a ,int b) {
int ans = 1;
while (b) {
if (b & 1) ans = (LL)ans * a % mod;
a = (LL)a * a % mod;
b >>= 1;
}
return ans;
}
int a = read() ,b = read();
signed main() {
printf("%d\n" ,(LL)a * pow(b ,mod - 2) % mod);
return 0;
}