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

题意简述

Link

\(\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;
}
posted @ 2021-04-25 13:09  recollector  阅读(65)  评论(0编辑  收藏  举报