1. 程式人生 > 實用技巧 >LeetCode 1382.將二叉搜尋樹變平衡

LeetCode 1382.將二叉搜尋樹變平衡

快速冪

閒扯

本蒟蒻數學不好(• ̀ω•́ )✧,想寫一篇快速冪的題解讓自己對其的瞭解更加深入。

演算法

題面

洛谷P1226快速冪

題目描述

給你三個整數\(b, p, k\)\(b ^ p \mod k\)

輸入格式

輸入只有一行三個整數,分別代表\(b, p, k\)

輸出格式

輸出一行一個字串\(b ^ p \mod k = s\) ,其中\(b, p, k\)分別為題目給定的值,\(s\)為運算結果。

演算法

我們在進行冪運算的時候將\(a\)自乘一次得到\(a ^ 2\),再把\(a ^ 2\)自乘一次變為\(a ^ 4\),接下來\(a ^ 8\)……,自乘\(n\)次後就變為了\(a ^ {2n}\)

,冪運算還有這樣的一種原理\(a ^ xa ^ y = a^{x + y}\)。最重要的是下一點,我們要求出的是\(a ^ b\),在這裡我們將\(b\)轉化成二進位制看一下,假設\(b = (39)_10\)等同於\(b = (100111)_2\),這些\(1\)分別代表十進位制中的\(32, 4, 2, 1\),那麼\(a ^ {39} = a ^ {32} \times a ^ 4 \times a ^ 2 \times a ^ 1\)。這樣來表示的話我們就可以大大降低時間複雜度到\(O(log_2n)\)
那麼程式碼應該如何實現呢?首先我們定義一個初始值\(base = a\)\(ans = 1\)
來記錄結果。我們通過一個\(while(b > 0)\)的迴圈來進行計算,我們的想法是當\(b\)在二進位制表示下的第\(i\)位如果為\(1\)那麼的話\(ans *= base;\)如果為\(0\)的話則繼續,同時無論哪種情況都要\(base *= 2\)使他自己變成平方,這時我們就需要用到一種神奇的方法來判斷第\(i\)位到第是什麼表示為\(if(b\) & \(i)\),&為按位與的意思,即為當兩者都是\(1\)的時候才會返回\(1\)否則返回\(0\),非常的巧妙;同時\(b >>= 1\)這個意思是\(b\)在二進位制的表示下向右移一位,\((100111)_2 <<= (10011)_2\)
這樣進行操作直到\(b\)變為\(0\)。同時注意需要在每一步進行的同時\(/mod k\),這樣才不會使答案溢位。

程式碼實現

#include<bits/stdc++.h>
using namespace std;
long long b,q,k;
long long quickpower(long long a,long long b){
	long long ans=1,base=a;
	while(b > 0){
		if(b & 1) ans=ans*base%k;
		base=base*base%k;
		b >>=1;
	}
	return ans;
}

int main(){
	cin>>b>>q>>k;
	int ans=quickpower(b,q);
	printf("%lld^%lld mod %lld=%lld",b,q,k,ans%k);
	return 0;
}

完結撒花ヾ(✿゚▽゚)ノ