ACM CSP竞赛笔记(二十一)——倍增:快速幂

参考课程是我高中信息竞赛邱老师的课程。

【17-1 倍增思想与快速幂】 https://www.bilibili.com/video/BV1hx4y1b7zZ/?share_source=copy_web\&vd_source=2c56c6a2645587b49d62e5b12b253dca

需要完整ACM CSP板子可以在资源找,我设置的0积分,如果要钱来B站私我!

倍增

快速幂

拆指数为二进制,每次看二进制是否要乘上对应的a^(k-1)

模板

b每次通过&1获取最后一位,通过最后一位是否为1判断ans是否要乘上a^(k-1)。然后a倍增,b去掉最后一位。

取余不变性 P1226

https://www.luogu.com.cn/problem/P1226

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;
long long a,b,p;
long long qpow(long long a,long long b){
    long long ans=1;
    // 先对底数取模,防止后续平方溢出
    a = a % p;
    while (b > 0) {
        // 如果 b 是奇数
        if (b & 1) {
            ans = (ans * a) % p;
        }
        // 底数平方,并立即取模(关键修正点)
        a = (a * a) % p;
        b >>= 1;
    }
    return ans;
}
int main(){
    cin>>a>>b>>p;
    cout<<a<<"^"<<b<<" mod "<<p<<"="<<qpow(a,b);
}

练习 P1965

https://www.luogu.com.cn/problem/P1965

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;

long long n,m,k,x;
//(x+10^k*m)%n=x%n+(10^k*m)%n=x%n+((10^k)%n*m%n)%n
int main(){
    cin>>n>>m>>k>>x;
    long long ans=1;
    long long a=10;
    long long b=k;
    a=a%n;
    while(b){
        if(b&1){
            ans=(ans*a)%n;
        }
        a=(a*a)%n;
        b>>=1;
    }
    long long temp=x%n+(ans*(m%n))%n;
    cout<<temp%n<<endl;
}