快速幂

任何正整数都可以写成若干个$2^i$ 相加的形式(十进制转二进制)

n为2的i次幂

  • 求$a^n$,其中n是2的i次幂,时间复杂度是O(logN):
    比如求$5^{16}$:
int a=5;    //底数
int i=4;    //16是2的4次幂
while(i--){
	a*=a;
}

n为任意正整数

  • 求$an$,其中n是任意正整数,把n写成若干个$2i$相加的形式
    比如求$5^{19}$:
    n=19=16+2+1
    $a{19}=a=a{16}*a2*a^1$

  • 十进制转二进制:

while(x){
	if(x%2==1){
		cout<<1<<endl;
	}
	else cout<<0<<endl;
	x/=2;    //右移,也可以写成x>>=1;
}
  • 得到二进制位的同时累乘结果,时间复杂度O(logx)
int quick_mul(int a,int x){   //求a^x
	int ans=1;
	//把a当作当前二进制位i对应的a的n次幂(初始i为1,初始n为2^(1-1))
	while(x){
		if(x%2==1){
			ans*=a;
		}
		x/=2;
		a*=a;
	}
}

模运算规则

  • (a+b)%p=(a%p+b%p)%p

  • (a-b)%p=(a%p-b%p)%p

  • (a*b)%p=(a%p * b%p)%p

  • (ab)%p=((a%p)b)%p

  • 快速幂过程中取模:相乘最后取模等效于乘的过程中取余

long long a, b, p;  
long long ans = 1;  
  
int main() {  
    cin >> a >> b >> p;    //求a^b,结果对p取模
    long long a1 = a, b1 = b;
    while (b) {
       if (b % 2 == 1) {
          ans=(ans*a)%p;
       }
       b /= 2;  
       a=(a*a)%p;
    }  
    cout << a1 << '^' << b1 << " mod " << p << '=' << ans << endl;  
    return 0;  
}
posted @ 2026-04-03 23:43  mofei1116  阅读(3)  评论(0)    收藏  举报