C++——快速冪&二進制

說實話,本來是不想學這個的,總覺得學了十幾年十進制,非要用二進制可變扭了。但是,這個好像是必須得過去的坎,總沒道理總是拖着……

然後在進入正題之前,先說一個輕鬆的話題:

昨天,上c++實驗課的時候,有一個學ACM的學長來蹭課,老師檢查作業的時候看到學長寫了一個:

#define LL long long

然後,老師就問這是什麼,學長說,因爲懶,所以……blabla

然後老師又問long long是什麼……

……

學長很耐心得跟老師解釋

(╯‵□′)╯︵┻━┻我在旁邊都聽不下去了


好了,進入正題:

先談談二進制

先看看百度百科怎麼說

二進制是計算技術中廣泛採用的一種數制二進制數據是用0和1兩個數碼來表示的數。它的基數爲2,進位規則是“逢二進一”,借位規則是“借一當二”,由18世紀德國數理哲學大師萊布尼茲發現。當前的計算機系統使用的基本上是二進制系統,數據在計算機中主要是以補碼的形式存儲的。計算機中的二進制則是一個非常微小的開關,用“開”來表示1,“關”來表示0。


定義什麼的都不重要,主要是二進制和十進制的轉換//這個考試是會考的……

二進制轉十進制(整數)

先舉個栗子:

二進制的101如果轉化爲十進制是多少呢?

首先,要確立一個思想,也就是在計算機中,大部分都是從0開始計數→所以想知道(101)2是多少,就從右邊第一項開始標號:012;接着就是計算了(101)2=1*2^2+0*2^1+1*2^0=5(相同顏色代表其相關)

好吧,我不得不承認百度寫的還是不錯的,就截圖放上來吧

二進制轉十進制(小數)

(見截圖↑)


十進制轉二進制

若爲整數就是不停地除以二然後取餘,若爲小數就是乘以二再取整

接下來談一談有關運算

--------------------以下內容來自B站某UP主上傳的視頻-------------------

---------------------------------------以上----------------------------------------

個人認爲這個視頻已經講的很清楚了(但是時間久遠,我也不記得是哪個了,現在只有PPT還留着//其實是截圖……)

好了,做了這麼長的鋪墊



現在,我們來談談快速冪的問題

說到冪函數,當然會聯想到cmath頭文件下的函數pow(底數,指數),但是如果自己寫函數呢?

我想大多數人會跟我一樣這麼寫:

#include <iostream>
using namespace std;

int power(int a,int b)
{
    int ans=1;
    for(int i=1;i<=b;i++)
    {
        ans*=a;
    }
    return ans;
}
int main()
{
    int a,b;
    int num;
    while(cin>>a>>b)
    {
        num=power(a,b);
        cout<<num<<'\n';
    }
    return 0;
}

這麼寫當然沒有問題,唯一的問題就是——時間複雜度(動不動就TLE還是很絕望的),這樣寫,時間複雜度大約能達到O(n),雖然看起來也沒多大,但是使用快速冪可以把時間複雜度降到O(log₂N)。

核心代碼如下:

int power(int a,int b)
{
    int r=1,base=a;
    while(b!=0)
    {
        if(b%2) r*=base;
        base*=base;
        b/=2;
    }
    return r;
}
順便引用快速冪講解
代碼很短,死記也可行,但最好還是理解一下吧,其實也很好理解,以b==11爲例,b=>1011,二進制從右向左算,但乘出來的順序是 a^(2^0)*a^(2^1)*a^(2^3),是從左向右的。我們不斷的讓base*=base目的即是累乘,以便隨時對ans做出貢獻。

  其中要理解base*=base這一步:因爲 base*base==base2,下一步再乘,就是base2*base2==base4,然後同理  base4*base4=base8,由此可以做到base-->base2-->base4-->base8-->base16-->base32.......指數正是 2^i ,再看上面的例子,a¹¹= a1*a2*a8,這三項就可以完美解決了,快速冪就是這樣。

  順便囉嗦一句,由於指數函數是爆炸增長的函數,所以很有可能會爆掉int的範圍,根據題意選擇 long long還是mod某個數自己看着辦。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章