P2613 【模板】有理数取余
给出一个有理数 c=ba,求 cmod19260817 的值。
看到这道题时
- 第一眼:好像很简单啊
- 第二眼:a,b≤1010001?!!
- 第三眼:卧槽这啥玩意?!!
要做这道题,我们来介绍一个新的东西~~(主要是本蒟蒻不会exgcd(欧几里得扩展)~~
P 是一个质数
令 b′ 为 b 的逆元,那么有b×b′≡1(modP)
有 ba≡ba×1≡ba×(b×b′)≡a×b′(modP)
显然可以看出 b′ 的值为 b1
但是除以 b 与乘以 b1 是一样的啊,怎么办呢?
定理内容:如果 p 是一个质数,而整数 a 不是 p 的倍数,则有ap−1≡1(modp)
你可以选择跳过这部分
证明部分 p 是一个质数
首先我们考虑一个前置定理:
若gcd(c,p)=1,且ac≡bc(modp),那么有a≡b(modp)
证:
又∵ac≡bc(modp)∴(a−b)c≡0(modp)∴(a−b)c是p的整数倍∵gcd(c,p)=1∴a−b≡0(modp)即a≡b(modp)
证毕
然后我们进入正题,假设有正整数 a(a<p) 满足条件 gcd(a,p)=1,那么我们将 a 乘上 1∼p−1 后可以构成一个 modp 的完全剩余系
证:
又假设存在xa≡ya(modp),且x=y∵gcd(a,p)=1∴原式成立当且仅当x≡y(modp)∵x,y∈[1,p−1]∴x≡y(modp)当且仅当x=y,与已知条件矛盾∴假设不成立,原命题成立
证毕
接下来证明 ap−1≡1(modp)
证:
又∵1,2,⋯,p−1是modp的完全剩余系∴有1×2×⋯×p−1≡a×2a×⋯×(p−1)a(modp)即(p−1)!≡(p−1)!×ap−1(modp)∵p是质数∴gcd((p−1)!,p)=1∴ap−1≡1(modp)
证毕
根据费马小定理,显然 b′=bP−2
什么?不显然吗?
∵b′×bbP−1∴b′×b∴b′≡1(modP)≡1(modP)≡bP−1(modP)=bP−2
那么 ba=a×bP−2
然后我们就可以用快速幂轻松 A 掉这题了(ps:虽然快速幂让我们不需要高精了,但long long还是要的
#include<cstdio>
const int MOD = 19260817;
inline long long read() {
long long X = 0, flag = 1; char ch = getchar();
while(ch < '0' || ch > '9') {if(ch == '-') flag = 0; ch=getchar();}
while(ch >= '0' && ch <= '9') {X = (X * 10 + (ch ^ 48)) % MOD; ch = getchar();}
return flag ? X : -X;
}
long long a, b;
long long QuickPow(long long x, long long y) {
long long ans = 1, k = MOD - 2;
while(k) {
if(k & 1) ans = ans * x % MOD;
x = x * x % MOD;
k >>= 1;
}
return ans * y % MOD;
}//快速幂不建议这样写,还是用模板比较好
int main() {
a = read(); b = read();
if(b) printf("%lld\n", QuickPow(b, a));
else printf("Angry!\n");
return 0;
}