专栏文章

题解:P1226 【模板】快速幂

P1226题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@miq1pxvh
此快照首次捕获于
2025/12/03 21:31
3 个月前
此快照最后确认于
2025/12/03 21:31
3 个月前
查看原文

题目大意

2a,b2312\le a,b \le2^{31}2p2312\le p \le2^{31} 的限制下计算 abmodpa^b\mod p 的结果。

大体思路

由于 aabb 都很大,O(b)O(b) 的暴力相乘肯定会超时,我们需要想出 O(logb)O(\log b) 的做法来处理幂运算。
我们首先要知道一个小学知识:
ab×ac=ab+ca^b\times a^c=a^{b+c}
(ab)c=a(b×c)(a^b)^c=a^{(b\times c)}
类似于倍增的二进制拆位思路,我们把 aba^b 可以拆成由若干个 a(2n)a^{(2^n)} 相乘组成的式子,这样我们就能把复杂度降到 O(logb)O(\log b)
拆的办法也很显然,把 bb 拆成由若干个由 2n2^n 组成的式子,然后再将这几个 a2xa^{2^x} 乘起来。
就如样例的例子,2102^{10}
10=23+2110=2^3+2^1
所以:
210=223×2212^{10}=2^{2^3}\times 2^{2^1}

部分代码讲解

CPP
int ans=1;
while(b) {
  if(b%2==1) {
    ans=ans*a%p;
  }
  b/=2;
  a=a*a%p;
}
我们对 bb 进行处理,如果其不可以被二整除,那么我们就先把 aba^b 拆成 ab1×aa^{b-1}\times a,用变量 ansans 记录这些被分出来的 aa,可以被二整除或处理完后,我们将 bb 除以二,将 aba^b 拆为 ab/2×ab/2a^{b/2}\times a^{b/2},我们这里让当前的 aa 变为 a2a^2 即可,之后的处理保留这次的平方。

Code

CPP
#include<bits/stdc++.h>
using namespace std;
int main() {
	long long a,b,p;
	cin>>a>>b>>p;
	cout<<a<<"^"<<b<<" mod "<<p<<"=";
	int ans=1;
	while(b) {
		if(b%2==1) {
			ans=ans*a%p;
		}
		b/=2;
		a=a*a%p;
	}
	cout<<ans;
	return 0;
}
最后给大家一个考试时用的模板,作为自定义函数使用:
CPP
long long ksm(long long a,long long b){
	long long ans=1;
	while(b){
		if(b&1){
			ans=ans*a%mod;
		}
		b>>=1;
		a=a*a%mod;
	}
	return ans;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...