高精度之關於高精度的其他問題

2021-08-01 21:30:05 字數 1332 閱讀 1575

高精度階乘其實就是加法的高階版,樸素的版本可以模擬階乘過程,首先階乘的資料必定不會太大,所以可以持續用高精度乘以低精度進行計算。

但是問題是當n!稍微大一點就會導致執行超時。所以可以把n!拆成n*(n-1),(n-2)*(n-3)或是更少的組進行計算,最後再採用高精度乘以高精度合併結果。

當給出的資料位數很大時帶來的問題是陣列可能必須開到很大並且相應的效率也會降低,所以我們希望讓陣列的乙個位置儲存更多的位數,並且考慮到陣列中元素大小的限制,乙個位置存四位數是最理想的,這也就是我們說的萬進製高精度。當然對於普通的高精度加法和減法,儲存的位數可以相應擴大。**實現起來和普通高精度差不多,只是在取出元素時多取出幾位,並且進製改變一下就可以實現。

當然我個人認為對於noip競賽來說普通的高精度就足夠了,所以我沒有再去實現**。

考到算我輸

首先要介紹一下普通的快速冪演算法,其實是利用了反覆平方加速的技術。

例如當n=5時,我們可以

(1)a*a=a^2

(2)a^2*a^2=a^4

(3)a^4*a=a*5

這樣只要成三次就可以了,對應的當n增大時,省下的時間會更多。

實際程式設計可以採用降冪的方法,即a^n=(a^2)^n/2.**片段如下,

其中函式plus(x,y,z)表示將x*y的值賦值給ans,ans為最終的結果。

ans=1;

while(n>1)

plus(ans,a,ans);//還有因為n是奇數乘過來的數

對應的轉換為高精度問題時只需將plus改為高精度,並將a和ans的儲存方式改為陣列。這個時候會有乙個問題影響到程式的效率,就是當計算ans乘以a的值時,我們可能會將計算的值存到乙個臨時陣列裡,計算完後再把臨時陣列裡的數存回ans,這必然會拉低速度,所以我們其實可以全程採用乙個指標指向實際的ans陣列,每次計算結束後,交換指標位址。注意別忘了每次把「臨時陣列」騰空。

但是對於指標真的把握不好,所以建議開乙個二維陣列,然後持續滾動第一維。

還有就是,開始的時候我以為下面這段的思想也是快速冪:

inline long long add(int a,int n)

return (add(a,n/2)*add(a,n/2)*up)%k;//重複計算add(a,n/2)

}

但是後來才發現,快速冪是將通過將a的值擴大做到對計算進行降冪,這樣原來需要乘很多次a但是我只是對a的值擴大了一次就可以少乘很多次,這樣就節省了時間。而上面的這段**實質上是乙個拆分問題的過程,它只是把問題拆開,分開算,而沒有進行任何的優化,所以時間複雜度和普通冪運算是一樣的。

這些問題都是建立在普通高精度之上的,所以對於基礎的問題一定要掌握。

高精度除法(高精度除以高精度)

先貼乙個簡單的高精度除以單精度的 include include include using namespace std int main else ys ys 10 a i 0 while c i 0 i for int j i j 0 j printf d c j if ys printf d ...

高精度除高精度

演算法流程 第一步,讀入被除數 a 和 除數 b,判斷是否 a b,是則輸出 0 並結束演算法,否則令 answer 0 第二步,令餘數 remainder 0,令 i 從被除數最高位的下標開始 第三步,令 remainder remainder 10 a i 令 c 9 第四步,判斷是否 b c ...

高精度除以高精度

原 題 高精除以高精,求它們的商和餘數。演算法分析 高精除以高精是用減法模擬除法,對被除數的每一位都減去除數,一直減到當前位置的數字 包括前面的餘數 小於除數 由於每一位的數字小於10,所以對於每一位最多進行10次計算 代 碼 include include include using namesp...