快速幂讲解-And-AcWing-89. a^b-《算法竞赛进阶指南》

57 阅读1分钟

我正在参与掘金创作者训练营第5期

@TOC

快速幂

题目描述

aabb次方对modmod取模的值

1a,b,mod1091\leq a,b,mod\leq 10^9

问题分析

每个正整数可以唯一表示为若干指数不重复的22的次幂的和。

bb在二进制表示下有KK位,其中第i(0i<k)i(0\leq i < k)位的数字是cic_i,那么:

b=ck12k1+ck22k2++c020b=c_{k-1}2^{k-1}+c_{k-2}2^{k-2}+\cdots+c_02^0

因此:

ab=ack12k1ack22k2ac020a^b=a^{c_{k-1}2^{k-1}}*a^{c_{k-2}2^{k-2}}*\cdots*a^{c_02^0}

也就是说如果bb的第iicic_i00,那么aci2ia^{c_{i}2^{i}}就等于a0=1a^0=1;如果cic_i11,那么就等于a2ia^{2^i}

又有a2i=(a2i1)2a^{2^i}=(a^{2^{i-1}})^2,而k=log2(b+1)k=log_2(\lceil b+1\rceil)\lceil\rceil表示向上取整),故时间复杂度为O(log2b)O(log_2b)

所以每次取bb中的11位(b&1,b>>=1b\&1,b>>=1),每次aa都平方(a=aa%moda=a*a\%mod),如果bb的这一位是11就累积到ansans中。


快速幂模板

typedef long long ll;

ll power(ll a, ll b, ll mod)
{
    ll ans = 1 % mod;
    while (b)
    {
        if (b & 1)
            ans = ans * a % mod;
        a = a * a % mod;
        b >>= 1;
    }
    return ans;
}

如果要用int:

typedef long long ll;

int power(int a, int b, int mod)
{
    int ans = 1 % mod;
    while (b)
    {
        if (b & 1)
            ans = (ll)ans * a % mod;
        a = (ll)a * a % mod;
        b >>= 1;
    }
    return ans;
}

AcWing-89. a^b

传送门

Problem Description

aabb次方对modmod取模的值

Tips

1a,b,mod1091\leq a,b,mod\leq 10^9


AC代码

/*
 * @Author: LetMeFly
 * @Date: 2021-07-26 17:29:09
 * @LastEditors: LetMeFly
 * @LastEditTime: 2021-07-26 17:33:08
 */
#include <bits/stdc++.h>
using namespace std;
#define mem(a) memset(a, 0, sizeof(a))
#define dbg(x) cout << #x << " = " << x << endl
#define fi(i, l, r) for (int i = l; i < r; i++)
#define cd(a) scanf("%d", &a)
typedef long long ll;

int power(int a, int b, int mod)
{
    int ans = 1 % mod;
    while (b)
    {
        if (b & 1)
            ans = (ll)ans * a % mod;
        a = (ll)a * a % mod;
        b >>= 1;
    }
    return ans;
}

int main()
{
    int a, b, c;
    cin >> a >> b >> c;
    cout << power(a, b, c) << endl;
    return 0;
}

同步发文于我的CSDN,原创不易,转载请附上原文链接哦~
Tisfy:letmefly.blog.csdn.net/article/det…