指数循环节(降幂)

本文介绍了一种处理大指数运算的降幂方法,通过欧拉定理和快速幂算法,实现对大数指数的有效计算。代码示例展示了如何求解特定形式的指数表达式模数问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文转自(侵删https://blog.youkuaiyun.com/GreatJames/article/details/77162961

指数循环节

在有些题目中我们需要对指数进行降幂处理才能计算。比如计算

 

       

 

其中

 

这里由于很大,所以需要进行降幂。那么实际上有如下降幂公式

 

        

 

给定的值,求的值,其中

代码: 

#include <iostream>
#include <string.h>
#include <stdio.h>
 
using namespace std;
const int N = 1000005;
typedef long long LL;
 
char str[N];
 
int phi(int n)//求φ(n)
{
    int rea = n;
    for (int i = 2; i * i <= n; i++)
    {
        if (n % i == 0)
        {
            rea = rea - rea / i;
            while (n % i == 0)
            {
                n /= i;
            }
        }
    }
    if (n > 1)
    {
        rea = rea - rea / n;
    }
    return rea;
}
 
LL multi(LL a, LL b, LL m)//快乘a*b%m
{
    LL ans = 0;
    a %= m;
    while (b)
    {
        if (b & 1)
        {
            ans = (ans + a) % m;
            b--;
        }
        b >>= 1;
        a = (a + a) % m;
    }
    return ans;
}
 
LL quick_mod(LL a, LL b, LL m)//快速幂a^b%mod
{
    LL ans = 1;
    a %= m;
    while (b)
    {
        if (b & 1)
        {
            ans = multi(ans, a, m);
            b--;
        }
        b >>= 1;
        a = multi(a, a, m);
    }
    return ans;
}
 
void Solve(LL a, char str[], LL c)//a^str%c
{
    LL len = strlen(str);
    LL ans = 0;
    LL p = phi(c);
    if (len <= 15)
    {
        for (int i = 0; i < len; i++)
        {
            ans = ans * 10 + str[i] - '0';
        }
    }
    else
    {
        for (int i = 0; i < len; i++)
        {
            ans = ans * 10 + str[i] - '0';
            ans %= p;
        }
        ans += p;
    }
    printf("%I64d\n", quick_mod(a, ans, c));
}
 
int main()
{
    LL a, c;
    while (~scanf("%I64d%s%I64d", &a, str, &c))
    {
        Solve(a, str, c);
    }
    return 0;
}

 

### 欧拉降幂算法概述 欧拉降幂是一种用于解决指数运算中底数较大而指数非常大的问题的技术。其核心思想在于利用欧拉定理简化计算过程,从而降低复杂度并提高效率。 #### 数学基础 欧拉定理指出,在满足 \( \gcd(a, m) = 1 \) 的条件下,有如下关系成立: \[ a^{\phi(m)} \equiv 1 \ (\text{mod} \ m), \] 其中 \( \phi(m) \)欧拉函数,表示小于等于 \( m \) 且与 \( m \) 互质的整数个数[^2]。 基于此理论,当面对形如 \( a^n \mod m \) 的问题时,可以通过将指数 \( n \) 替换为其对 \( \phi(m) \) 取模后的值来减少计算量。具体而言, \[ a^n \mod m = a^{(n \mod \phi(m))} \mod m. \] 需要注意的是,上述结论仅适用于 \( \gcd(a, m) = 1 \)[^3]的情况;若两者不互素,则需进一步分析具体情况。 #### 实现细节 以下是采用C++语言编写的欧拉降幂实现代码: ```cpp #include <bits/stdc++.h> #define int long long const int MOD = 1e9 + 7; using namespace std; // 快速模板 int fast_pow(int base, int exp){ int result = 1 % MOD; // 初始化结果为1取模MOD while(exp > 0){ if (exp & 1LL) { // 如果当前位为1 result = (__int128(result) * base) % MOD; // 使用__int128防止溢出 } base = (__int128(base) * base) % MOD; // 平方基数 exp >>= 1; // 移除最低位 } return result; } // 计算欧拉函数φ(x) int euler_phi(int x){ int res = x; for(int i=2;i*i<=x;i++){ if(x % i == 0){ res -= res / i; while(x % i == 0)x /= i; } } if(x>1)res -= res/x; return res; } signed main(){ ios::sync_with_stdio(false); cin.tie(NULL); int A,B,M; cin>>A>>B>>M; // 特殊情况处理:如果M为1,任何数对其取模都为0 if(M == 1){ cout<<0<<"\n"; return 0; } // 当GCD(A,M)!=1时需要特殊考虑,这里省略部分逻辑 // 否则按照常规流程执行 int Phi_M=euler_phi(M); // 获取φ(M) // B可能极大,因此先将其缩小至合理范围 int reduced_B=B%(Phi_M); // 输出最终结果 cout<<fast_pow(A,reduced_B)%M<<"\n"; return 0; } ``` 该程序首先定义了一个`fast_pow()`函数用来高效完成次运算,并提供了辅助工具`euler_phi()`以计算任意正整数对应的欧拉数值。随后主函数读入三个参数\(a\)、\(b\)以及模数\(m\),并通过调用前述组件实现了完整的欧拉降幂操作[^4]。 ### 注意事项 尽管上述方法有效解决了大部分场景下的需求,但在某些特定情况下仍可能存在局限性。例如当模数本身具有较高次形式(比如完全由某个单一因子构成),可能会导致递归过程中无法正常缩减规模等问题[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值