杭電上有一道十分讓初學者十分蛋疼的題 a^b%m,看似很簡單,但題目要求b的範圍是(0,1000000000],a是32位整數範圍,m是小於40000的整數。咋一看這題,貌似要用高精度。但是赤裸裸的用高精度的話,在空間複雜度以及時間複雜度上都是傷不起的!!
讓我們來換個思路,有一定數學基礎的人都知道,(a*b)%m 是等價於 a%m * b%m的,這樣好了,可以不用高精度了,但是完全模擬的話,在規定時間內是不可能出解的。
我們再想想,是否可以減小計算量呢?有了!我們可以將 a^b 分解成為 t1*a^1+t2*a^2+t3*a^3+.....(ti=0 或者 1),我們預處理下,算出a^2i,然後將b變為二進位制,乘以相應的項,我們就得到了最後的結果。運算次數大大減少了,這樣是可以在規定時間內出解的。
如果我們覺得上面的方法太麻煩的話,下面的遞迴**就十分簡單了。
#include
using namespace std;
int run(int a,int b,int m)else
}int main()
這其實是利用了乙個分治的思想,要想求a^b1,先求出a^b2(其中b2=b1/2),而要求a^b2,又得求出a^b3(其中b3=b2/2)..........直到bi =1。整個問題的時間複雜度就變得非常低了。最多幾十次基本操作就能得到結果(有木有感覺很神奇)。其實我們還可以將這個演算法求斐波拉契數列的第10000000項對m取餘,這樣用到矩陣的乘法,下面給出具體的矩陣推導以及**。
[img]
#include
using namespace std;
class matrix
matrix(int hei,int wid)
}system("pause");
return 0;
}
分治就是分而治之的縮寫,分治的思想並不侷限於這道題,它能極大的提高演算法的效率。所以掌握它是十分必要的。
演算法 分治演算法
分治策略主要利用遞迴來解決問題,它包括以下三個步驟 分解 將問題分解為一與原問題類似並且比原問題規模更小的子問題 解決 當分解的子問題足夠小時,直接給出答案,否則用遞迴打方式求解 合併 將子問題的解合成原問題的解 下面考慮乙個簡單的利用分治演算法的歸併排序的例子 問題的形式化描述如下 輸入 a是 乙...
演算法 分治演算法
leetcode 169.多數元素 應用舉例 通過應用舉例分析理解分治演算法的原理其實並不難,但是要想靈活應用並在程式設計中體現這種思想中 卻並不容易。所以,這裡這裡用分治演算法應用在排序的時候的乙個栗子,加深對分治演算法的理解。相關概念 一般通過計算有序對或者逆序對的個數,來表示資料的有序度或逆序...
演算法複習 分治演算法
先來看乙個經典的二分查詢例子。int binarysearch vector nums,int target return 1 時間複雜度是 o logn 我們看到,二分查詢貫徹了分治的思想。當我們要解決乙個輸入規模較大 不妨設為 n 的問題時,可以將這個問題分解成 k 個不同的子集,如果能得到 k...