首先我们要知道,正常计算的话,指数优先级最高,因此得先计算指数,比如:
2
3
2
=
512
2^{3^2}=512
232=512
欧拉定理的关键在于,它允许我们通过减少计算的指数大小来简化模运算。
经过仔细研究(看题解的思路),蓝桥杯这个题应该是出错了,这个题的指数叫作:广义高阶幂塔,应当递归求解,而使用欧拉函数的方法不适用,所以现将题目改成:
对
(
⋅
⋅
⋅
(
(
2
3
)
4
)
5
⋅
⋅
⋅
)
2023
的值对
2023
取模的结果。
对(···((2^3)^4)^5···)^{2023}的值对2023取模的结果。
对(⋅⋅⋅((23)4)5⋅⋅⋅)2023的值对2023取模的结果。
1、无脑的想法:
指数模
+快速幂
(错的)
#include <iostream>
using namespace std;
int main()
{
int result = 2023;//result 存储 指数
for(int i = 2022;i >= 2; --i){//遍历底数
int b = result;
int a = i;
int ans = 1;
while(b){
if((b & 1) == 1){
ans = (ans * a) % 2023;
}
a = (a * a) % 2023;
b >>= 1;
}
result = ans;
}
cout << result;//1259
return 0;
}
指数并不能直接取模!取模只在四则运算里面好用,在指数里面就不太能直接用了。
2
10
m
o
d
9
=
1024
m
o
d
9
=
7
2^{10} mod\ 9 = 1024\ mod\ 9 = 7
210mod 9=1024 mod 9=7;
2
10
m
o
d
9
≠
2
m
o
d
9
=
2
2^{10} mod\ 9\ ≠2\ mod\ 9=2
210mod 9 =2 mod 9=2
可以证明指数不能随便取模。
普通的取模运算只能运用于加减乘除(四则运算) 下面是这些基本算术操作在模运算下的特性:
-
加法(Addition):
- ( a + b ) m o d n = [ ( a m o d n ) + ( b m o d n ) ] m o d n (a + b) \mod n = [(a \mod n) + (b \mod n)] \mod n (a+b)modn=[(amodn)+(bmodn)]modn
- 加法的模运算遵循分配律。
-
减法(Subtraction):
- ( a − b ) m o d n = [ ( a m o d n ) − ( b m o d n ) + n ] m o d n (a - b) \mod n = [(a \mod n) - (b \mod n) + n] \mod n (a−b)modn=[(amodn)−(bmodn)+n]modn
- 减法也遵循类似的规则,但要注意结果保持非负。
-
乘法(Multiplication):
- ( a × b ) m o d n = [ ( a m o d n ) × ( b m o d n ) ] m o d n (a \times b) \mod n = [(a \mod n) \times (b \mod n)] \mod n (a×b)modn=[(amodn)×(bmodn)]modn
- 乘法在模运算中同样遵守分配律。
-
除法(Division):
- 除法在模运算中比较复杂。不能直接应用常规除法运算,需要用到乘法逆元。如果存在, a a a 在模 n n n 下的乘法逆元 a − 1 a^{-1} a−1 满足 a a − 1 ≡ 1 m o d n aa^{-1} \equiv 1 \mod n aa−1≡1modn。然后, a / b m o d n a / b \mod n a/bmodn 可以表示为 a × b − 1 m o d n a \times b^{-1} \mod n a×b−1modn。
在处理幂运算(如 a b m o d n a^b \mod n abmodn)时,不能直接对指数 b b b 应用普通的模运算,除非考虑到适当的数论属性(如欧拉函数 ϕ ( n ) \phi(n) ϕ(n)),这是因为幂运算涉及重复的乘法过程,指数的大小直接影响最终结果。因此,在涉及到幂运算时,需要谨慎处理指数的模运算,通常基于 ϕ ( n ) \phi(n) ϕ(n) 来简化指数大小。
2、有脑但不够的想法
费马小定理
(错的)
- 费马小定理:
费马小定理: a p − 1 ≡ 1 ( m o d p ) p 是质数 , g c d ( a , p ) = 1 费马小定理:a^{p-1} ≡ 1(mod\ p)\ \ \ \ p是质数,gcd(a,p)=1 费马小定理:ap−1≡1(mod p) p是质数,gcd(a,p)=1
如果
2023
是质数,则
a
2022
≡
1
(
m
o
d
2023
)
如果2023是质数,则a^{2022} ≡ 1(mod\ 2023)
如果2023是质数,则a2022≡1(mod 2023)
如果
2023
是质数,则
a
2023
≡
a
(
m
o
d
2023
)
如果2023是质数,则a^{2023} ≡ a (mod\ 2023)
如果2023是质数,则a2023≡a(mod 2023)
由于
a
=
b
2022
,且
b
2022
≡
1
(
m
o
d
2023
)
由于a = b^{2022},且b^{2022} ≡ 1(mod\ 2023)
由于a=b2022,且b2022≡1(mod 2023)
则有,
a
2023
≡
a
≡
1
(
m
o
d
2023
)
,其中
a
=
2
3
4
(
⋅
⋅
⋅
)
2022
则有,a^{2023} ≡ a ≡ 1\ (mod\ 2023),其中a = 2^{3^{4^{(···)^{2022}}}}
则有,a2023≡a≡1 (mod 2023),其中a=234(⋅⋅⋅)2022
因此得结果为
1
。
因此得结果为1。
因此得结果为1。
错误!因为2023压根不是质数。
不过我们需要注意的是,如果是按原题来理解:
而且这样做还存在一个问题,你把a看成一个整体考虑问题了,因为你把底数包裹起来了,然后看最顶层的指数,这就相当于
2
3
2
2^{3^2}
232,把
2
3
2^{3}
23看成一个整体了,这很显然与指数计算的方式相违背!
#include <iostream>
#include <cmath>
using namespace std;
int main()
{
int f = sqrt(2023);
for(int i = 2;i <= f;++i){
if(2023 % i == 0){
cout << i << " * " << 2023 / i << " = 2023"<<endl;
}
}
return 0;
}
输出:
7 * 289 = 2023
17 * 119 = 2023
3、正解
欧拉定理
: 数论基础
- 欧拉定理:
a ϕ ( n ) ≡ 1 ( m o d n ) , g c d ( a , n ) = 1 a^{\phi(n)} ≡\ 1(mod\ n),gcd(a,n)=1 aϕ(n)≡ 1(mod n),gcd(a,n)=1
令 b = c ϕ ( n ) + d ,则 a b ≡ a c ϕ ( n ) + d ≡ a d ( m o d n ) b\ =\ c\phi(n)+d,则a^{b} ≡\ a^{c\phi(n)+d}≡\ a^d(mod\ n) b = cϕ(n)+d,则ab≡ acϕ(n)+d≡ ad(mod n)
因此 a b ≡ a b m o d ϕ ( n ) ( m o d n ) a^{b} ≡\ a^{b\ mod\ \phi(n)}(mod\ n) ab≡ ab mod ϕ(n)(mod n)。
因此使用欧拉定理可以“模”去一部分指数。
因此由于本题的底数是 2 2 2, 2 2 2的任意次幂都和 2023 2023 2023互质,所以满足欧拉定理。本题最外层可以认为是 x 2023 ≡ x 2023 m o d ϕ ( 2023 ) ( m o d 2023 ) x^{2023}≡\ x^{2023\ mod\ \phi(2023)}(mod\ 2023) x2023≡ x2023 mod ϕ(2023)(mod 2023)
- 欧拉函数的计算方式:
其中 p i p_i pi是 n n n的所有质因数,计算方式应该是 ϕ ( n ) = n × ∏ i = 1 S ( p i − 1 p i ) \phi(n)=n×\prod_{i=1}^{S}(\frac{p_i-1}{p_i}) ϕ(n)=n×∏i=1S(pipi−1)。
根据上述不过我们需要注意的是,如果是按原题来理解:
令计算的指数塔是
2
a
m
o
d
2023
2^a\ mod\ 2023
2a mod 2023,则结果为
2
a
m
o
d
ϕ
(
2023
)
m
o
d
2023
2^{a\ mod\ \phi(2023)} mod 2023
2a mod ϕ(2023)mod2023,也就是
2
a
m
o
d
1632
m
o
d
2023
2^{a\ mod\ 1632}\ mod\ 2023
2a mod 1632 mod 2023,那么接下来需要知道
a
m
o
d
1632
a\ mod\ 1632
a mod 1632的大小,但指数塔
a
=
3
b
a = 3^b
a=3b,此时计算的指数塔是
3
b
m
o
d
1632
3^b\ mod\ 1632
3b mod 1632,接下来
b
m
o
d
ϕ
(
1632
)
b\ mod\ \phi(1632)
b mod ϕ(1632)。
好好好,这样不一定互质了,所以问题太大了。
正确的解法:
#include<bits/stdc++.h>
using namespace std;
#define int long long
//欧拉函数
int get_eular(int n){
int phi=n;
for(int i=2;i<=n/i;i++){
if(n%i) continue;
while(n%i==0) n/=i;
phi=phi/i*(i-1);
}
if(n>1) phi=phi/n*(n-1);
return phi;
}
//快速幂
int quick(int base, int x, int mod){
int res=1;
while(x){
if(x&1) res=res*base%mod;
base=base*base%mod;
x>>=1;
}
return res;
}
signed main(){
int a=get_eular(2023);
int t=2023;
for(int i=2022;i>=3;i--){
t=quick(i,t,a);
};
t=quick(2,t,2023);
cout<<t<<endl;
return 0;
}
究其原因,我是真没想清楚。