【2023次方 / B】

题目

在这里插入图片描述

2025.2.26更新 正解

#include <bits/stdc++.h>
using namespace std;
using ll = long long;

const int N = 2024;

int primes[N], cnt, phi[N];
bool st[N];

void get_phi(int n)
{
	phi[1] = 1;
	for(int i = 2; i <= n; i++)
	{
		if(!st[i]) primes[++cnt] = i, phi[i] = i-1;
		for(int j = 1; j <= cnt && primes[j] <= n / i; j++)
		{
			st[i * primes[j]] = 1;
			if(i % primes[j] == 0)
			{
				 phi[i * primes[j]] = primes[j] * phi[i]; //不互质,i有所有质因子,提出常数primes[j]
				 break;
			}
			else phi[i * primes[j]] = phi[i] * (primes[j] - 1); //互质,可积
		}
	}
}
ll qmi(ll base, int expo, int mod)
{
	ll retv = 1;
	
	while(expo)
	{
		if(expo & 1) retv = retv * base % mod;
		base = base * base % mod;
		expo >>= 1;
	}
	
	return retv;
}
int rec(int x, int mod)
{
	if(x == 2023) return 2023 % phi[mod] + phi[mod];
	else return qmi(x, rec(x+1, phi[2023]) + phi[mod], mod);
}
int main()
{
	get_phi(2023);
	
	printf("%d", rec(2, 2023));
}

(老内容,不建议看)思考

  • 直接快速幂,mod值恒为2023:不可以哦,不存在这个等式 a b ≡ a b    m o d    p    ( m o d    p ) a^{b} \equiv a^{b \; mod \; p} \; (mod \; p) ababmodp(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) ap11(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) a20231a(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) b20221(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)=1ababmodϕ(p)(modp) 用这个
    • a b ≡ a b    ( m o d    p ) ,    b < ϕ ( p ) a^{b} \equiv a^{b} \; (mod \; p), \; b < \phi(p) abab(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) ababmodϕ(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=i1
    • 对于问题 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;
        else
            s.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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值