【2023次方 / B】
题目
思考
- 直接快速幂,mod值恒为2023:不可以哦,不存在这个等式 a b ≡ a b m o d p ( m o d p ) a^{b} \equiv a^{b \; mod \; p} \; (mod \; p) ab≡abmodp(modp)
- 采用小费马定理 a p − 1 ≡ 1 ( m o d p ) , ( g c d ( a , p ) = 1 ) a^{p-1} \equiv 1 \; (mod \; p) \;,( gcd(a,p)=1) ap−1≡1(modp),(gcd(a,p)=1),很可惜还是错的,因为2023不是质数(一个质因数为17)
- 设原式为 b 202 2 2023 m o d p b^{2022^{2023}} \; mod \; p b20222023modp
- a 2023 ≡ 1 ⋅ a ( m o d p ) a^{2023} \equiv 1 \cdot a \; (mod \; p) a2023≡1⋅a(modp),原式子被化简为 b 2022 m o d p b^{2022} \; mod \; p b2022modp
- b 2022 ≡ 1 ( m o d p ) b^{2022} \equiv 1 \; (mod \; p) b2022≡1(modp),答案为1
- 采用欧拉定理,很可惜需要不断嵌套,而且条件不会一直满足
- a ϕ ( p ) ≡ 1 ( m o d p ) , g c d ( a , p ) = 1 ⇒ a b ≡ a b m o d ϕ ( p ) ( m o d p ) a^{\phi(p)} \equiv 1 \; (mod \; p) \;, gcd(a,p) = 1 \; \Rightarrow a^{b} \equiv a^{b\;mod\;\phi(p)} \; (mod \; p) aϕ(p)≡1(modp),gcd(a,p)=1⇒ab≡abmodϕ(p)(modp) 用这个
- a b ≡ a b ( m o d p ) , b < ϕ ( p ) a^{b} \equiv a^{b} \; (mod \; p), \; b < \phi(p) ab≡ab(modp),b<ϕ(p)
- a b ≡ a b m o d ϕ ( p ) + ϕ ( p ) ( m o d p ) , b ≥ ϕ ( p ) a^{b} \equiv a^{b\;mod \; \phi(p) + \phi(p)} \; (mod \; p), \; b \ge \phi(p) ab≡abmodϕ(p)+ϕ(p)(modp),b≥ϕ(p)
- 采用周期法
- 首先不断计算 a m o d p , a 2 m o d p . . . . . . a n m o d p a\;mod\;p,\;a^{2}\;mod\;p......a^{n}\;mod\;p amodp,a2modp......anmodp,直到出现循环,假设指数为 i i i 时出现重复
- 则周期 T = i − 1 T = i-1 T=i−1
- 对于问题 a j m o d p a^{j}\;mod\;p ajmodp,我们可以化简指数为 j m o d T j\;mod\;T jmodT 即可,注意若值为0,则改值为T,总之就是映射到 [ 1 , T ] [1,T] [1,T] 上的某一元素
做法
- 计算 2 i m o d 2023 , T = 408 2^{i} \;mod\; 2023 ,\;T = 408 2imod2023,T=408
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
set<LL> s;
int main()
{LL a = 2, mod = 2023;int i;LL op = a;for (i = 1;; i++){LL tmp = op % mod;if (s.count(tmp))break;elses.insert(tmp);op = (op * a) % mod; // 注意,这个求模运算不影响指数,是乘法法则的运用}int T = i - 1;cout << T;
}
- 计算 3 i m o d 408 , T = 16 3^{i} \;mod\; 408 ,\;T = 16 3imod408,T=16
- 计算 4 i m o d 16 = 0 4^{i} \;mod\; 16 = 0 4imod16=0 (其实不用计算,因为16是4的倍数,因此 i > = 2 i >= 2 i>=2 就可以 得到结果为 0)
- 计算 3 16 m o d 408 = 273 3^{16} \;mod\; 408 = 273 316mod408=273
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
LL qmi(LL base, LL x, LL mod)
{LL retv = 1;while (x){if (x & 1)retv = (retv * base) % mod;base = (base * base) % mod;x >>= 1;}return retv;
}
int main()
{LL base = 3, x = 16, mod = 408;cout << qmi(base, x, mod);
}
- 计算 2 273 m o d 2023 = 869 2^{273} \;mod\; 2023 = 869 2273mod2023=869
解释
为什么有些做法不嵌套欧拉函数,只用了一层欧拉函数也可以得到这个答案?
- 这是因为: 2 的指数需要 ϕ ( 2023 ) \phi(2023) ϕ(2023) 来化简 (对应 以3为底数的快速幂 mod = ϕ ( 2023 ) \phi(2023) ϕ(2023),这个做到了),3 的指数需要 ϕ ( ϕ ( 2023 ) ) \phi(\phi(2023)) ϕ(ϕ(2023)),这个没做到
- 但是如周期法所示,3的指数,以4为底的上层对答案的影响等效于令 3 的指数为 16,而 错误方法此时得到的指数是 1024, ϕ ( 2023 ) = 1632 \phi(2023) = 1632 ϕ(2023)=1632
- 1024 m o d 1632 = 1024 1024 \mod 1632 = 1024 1024mod1632=1024 与 16 映射到周期 T = 16 T = 16 T=16 的位置一致
- 总的来说,就是说下层一样处理,上层等效了,最狗血的是那个1024刚好是16倍数,而且没被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;
}