從零開始的演算法學習生活 高精度運算(2)

2021-10-25 14:31:02 字數 2725 閱讀 5112

二、高精度模板總結

回想一下a+b高精的實現,我們從豎式加法中得到啟發,發現了陣列實現大數加法的本質,那麼這裡我們不妨從豎式乘法的角度分析,通過下表來觀察其實質。

舉個例子,342*456=155,952,下表是每一位的運算過程。 數

第5位第4位

第3位第2位

第1位第0位a3

42b4

56a*b[0]

1824

12a*b[1]

1520

10a*b[2]

12168加和

1231

4634

12處理進製15

5952

結果155

952仔細觀察可以發現,對於某兩位之間的乘法運算結果a[i]*b[j],其對於最終結果的貢獻都在第i+j位上。利用這一條性質,我們可以先將所有的貢獻計算出來,最後進行進製處理,提公升了運算效率。

傳送門: 洛谷p1303(a*b problem)

附上ac**

#include

#include

using namespace std;

const

int max_n =

2002

;//最大位數

int a[max_n]

,b[max_n]

,c[max_n]

;int

main()

}int len = lena + lenb;

//兩數乘積的最大位數不超過兩數字數之和

for(

int i =

0;i < len;i++

)while

(!c[len-1]

)for

(int i =

max(

0,len-1)

;i >=

0;i--

)//這裡使用max函式是為了處理乘數為0的情況

//輸出

return0;

}

ps:此**的時間複雜度為o(n²),n為數的位數。若要進行優化,則可以通過快速傅利葉變換

來加速高精度乘法,將其優化為o(nlogn),由於比較複雜,在此不作深入說明。

到此,我們已經了解了用陣列模擬大數並進行加法與乘法的本質與方法,那麼有乙個很自然的問題,能不能使用乙個模板,使得每次需要使用高精度運算時,或者同時需要使用加法與乘法運算時,能夠使用同乙個模板進行運算呢?

根據c++的特性,我們可以通過封裝結構體,並過載運算子的方式來實現乙個高精度模板。

#define max_n 200

//封裝結構體

struct bignum

}int

&operator (

int i)

void

flatten

(int l)

while

(!a[len-1]

)}void

print()

}};//重置+(兩個大數相加)

bignum operator+

(bignum a,bignum b)

c.flatten

(len+1)

;return c;

}//重置*(兩個大數相乘)

bignum operator*

(bignum a,bignum b)

}int max_len = lena + lenb;

c.flatten

(max_len)

;return c;

}//重置*(大數與int型相乘)

bignum operator*

(bignum a,

int b)

c.flatten

(len+11)

;//int型的最大長度為10位

return c;

}

例題傳送門:洛谷p1009(階乘之和)

題目描述

用高精度計算出s=1

!+2!

+3!+

⋯+n!

(n≤50

)s = 1! + 2! + 3! + \cdots + n!(n \le 50)

s=1!+2

!+3!

+⋯+n

!(n≤

50)

輸入格式

乙個正整數 nnn。

輸出格式

乙個正整數 s

ss,表示計算結果。

輸入輸出樣例

輸入 #1113

33輸出 #1119

99

說明/提示

【資料範圍】

對於100

%100 \%

100%

的資料,1≤n

≤50

。1 \le n \le 50。

1≤n≤50

。階乘達到22的時候,已經超出了long long的儲存範圍,這裡利用前面寫封裝好的高精模板,就能輕鬆的解決此題。

新增上相應的標頭檔案後,就能正常執行啦!(這裡只貼出main函式模擬題意**)

int

main()

ans.

print()

;return0;

}

到此為止,高精度運算就暫時告一段落了,高精度運算的主要實質為陣列模擬大數進行逐位運算,理解起來不算非常複雜,而通過進一步封裝,得到的高精度模板能夠方便簡潔地實現相應的大數運算。

從零開始的大資料學習生活

雖然以前從沒有想到,但是未來就是這樣充滿了未知與奇妙 我竟然要開始有關程式設計的學習。與python和資料探勘最初的接觸充滿了陌生與惶恐,甚至有一點點冰冷的感覺。畢竟,我對程式設計的認知實在少之又少,過去的十幾年裡也從未想到過會走上這樣一條道路。看著陌生的文字,奇異的符號,滿屏荒唐,不由得讓人滿面辛...

NOIp,從零開始的程式生活

無論是什麼oj,接觸程式設計的第一題永遠都是 a b 問題 在許久之前,入門的時候大家學的都是pascal,因為它容易,直觀 var a,b longint begin readln a,b writeln a b end.但是它畢竟久了,現如今,大家學的都是c 從2019年起noi系列賽事只支援c...

網路安全 從零開始的CTF生活

1 ctf是什麼?ctf capture the flag,奪旗賽 起源於 1996 年 defcon 全球黑客大會,是網路安全愛好者之間的競技遊戲。2 比賽怎麼打?1 解題模式 與acm程式設計競賽 資訊學奧賽類似,以解決網路安全技術挑戰題目的分值和時間來排名。題目主要包含逆向 漏洞挖掘與利用 w...