同余
a
x
≡
b
(
m
o
d
m
)
ax\equiv b(mod m)
ax≡b(modm) 其中
d
=
g
c
d
(
a
,
m
)
∣
b
d=gcd(a,m)|b
d=gcd(a,m)∣b
x
x
x有
d
d
d个模
m
m
m不同余的解
欧拉降幂
广义欧拉降幂:只要判断b与
ϕ
(
p
)
\phi(p)
ϕ(p)的大小关系:
a
b
=
a
b
%
ϕ
(
p
)
a^{b}=a^{b\%\phi(p)}
ab=ab%ϕ(p)
b
<
ϕ
(
p
)
b<\phi(p)
b<ϕ(p)
a
b
=
a
b
%
ϕ
(
p
)
+
ϕ
(
p
)
a^{b}=a^{b\%\phi(p)+\phi(p)}
ab=ab%ϕ(p)+ϕ(p)
b
≥
ϕ
(
p
)
b\geq \phi(p)
b≥ϕ(p)
模板题
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
LL a, b, c, mod = 1e9+7;
LL qmi(LL a, LL b, LL p) {
LL res = 1;
while (b) {
if (b & 1) res = 1ll * res * a % p;
b >>= 1;
a = 1ll * a * a % p;
}
return res;
}
LL phi(LL x) { //返回x的欧拉函数值
LL res = x;
for (LL i = 2; i <= x / i; i ++) {
if (x % i == 0) {
res = res / i * (i - 1);
while (x % i == 0) x /= i;
}
}
if (x > 1) res = res / x * (x - 1);
return res;
}
LL sol(LL a, LL b, LL p) { //欧拉降幂
LL t = phi(p);
if (__gcd(a, p) > 1 && b >= t) return qmi(a, b % t + t, p);
else return qmi(a, b % t, p) % p;
}
int main() {
while(~scanf("%lld%lld%lld", &a, &b, &c)) {
LL t = sol(b, c, phi(mod));
printf("%lld\n",sol(a, t, mod));
}
return 0;
}
Gym - 101550E
求 n ( n − 1 ) ( n − 2 ) . . . 2 1 % m 求n^{(n-1)^{(n-2)^{...^{2^{1}}}}}\%m 求n(n−1)(n−2)...21%m的值
A
C
代码在幂数
b
<
模数
m
时,直接用快速幂可以
A
C
,但是用欧拉降幂继续递归求解会
W
A
。有解释说
b
<
ϕ
(
m
)
时不满足欧拉降幂的条件。
AC代码在幂数b<模数m时,直接用快速幂可以AC,但是用欧拉降幂继续递归求解会WA。有解释说b<\phi(m)时不满足欧拉降幂的条件。
AC代码在幂数b<模数m时,直接用快速幂可以AC,但是用欧拉降幂继续递归求解会WA。有解释说b<ϕ(m)时不满足欧拉降幂的条件。这种情况不就是
b
<
ϕ
(
p
)
b<\phi(p)
b<ϕ(p)的情况吗,但用这种写法确实会WA 。
#include <bits/stdc++.h>
#define MOD(a,b) a>=b?a%b+b:a
using namespace std;
typedef long long LL;
typedef long long ll;
LL a, b, c, mod = 1e9+7;
LL qmi(LL a, LL b, LL p) {
LL res = 1;
while (b) {
if (b & 1) res = 1ll * res * a % p;
b >>= 1;
a = 1ll * a * a % p;
}
return res;
}
LL phi(LL x) { //返回x的欧拉函数值
LL res = x;
for (LL i = 2; i <= x / i; i ++) {
if (x % i == 0) {
res = res / i * (i - 1);
while (x % i == 0) x /= i;
}
}
if (x > 1) res = res / x * (x - 1);
return res;
}
LL sol(LL a, LL p) { //AC
if (p == 1) return 0; //模数为1
if (a == 1) return 1; //底数为1
else if (a == 2) return 2 % p;
else if (a == 3) return 9 % p;
else if (a == 4) return 262144 % p;
//5^262144>1e9,超过模数的最大取值,用欧拉降幂
LL t = phi(p);
LL b = sol(a - 1, t);
return qmi(a, b % t + t, p);
}
LL sol2(LL a, LL p) { //WA
if (p == 1) return 0;
if (a == 1) return 1;
LL t = phi(p);
LL b = sol(a - 1, t);
if (b < t)return qmi(a, b % t, p);
return qmi(a, b % t + t, p);
}
int main() {
LL n, m;
cin >> n >> m;
cout << sol(n, m);
return 0;
}