關於RMQ問題的一些感悟

2021-07-28 00:04:49 字數 1738 閱讀 8394

一般就是4種解決辦法吧。

1、線段樹

2、樹狀陣列

3、st表

4、差分

樹狀陣列是一種很輕便的工具,編碼簡單,常數小,缺點是只能求和。不同版本的樹狀陣列能實現不同組合的單點,區間,詢問,修改。時間複雜度都是o(logn)。

st表也是一種很輕便的工具,編碼簡單,常數小,缺點是只能求最值,而且是離線演算法。預處理的時間複雜度是o(nlogn),但可以o(1)回答。

差分與其說是一種工具,不如說是一種小技巧。o(1)區間更新,o(n)離線,o(1)回答。一般用於解決區間覆蓋等相關問題。

具體來講就是假如區間[l,r]要加x。那就在a[l]+=x,a[r+1]-=x。離線就是求個字首和,然後就可以o(1)回答單點,如果求兩次字首和,就能o(1)回答區間。

一般用於解決那種只需要最後要輸出所有單點的答案的問題,比如hdu 1556 color the ball。就完全沒必要用線段樹區間更新來解。

或者用於解決區間相關問題,比如一些滑動視窗之類的問題。

上述的rmq都是一維線性的rmq,事實上還有很多二維線性的rmq問題。會用到一些上述工具的變種,比如:

1、二維線段樹

2、二維樹狀陣列

3、二維st表

4、二維差分

其實二維差分就是一種動態規劃啦。一般用於解決矩形內計數的問題。dp[i][j]表示前i行與前j列一共有多少個東西,然後你就可以o(1)回答每個矩形內有多少個東西啦。

上述rmq都是線性的rmq,事實上還有很多非線性的rmq問題,比如樹,圖上的。

圖上的不說了,我自己胡扯的,有沒有也不知道,感覺更像是轉化成其他問題來解決,大白p234那一題算不算呢?

就說樹上的吧,其實依然是上述4種工具的變種啦。

1、樹鏈剖分

2、。。。???。。。

3、lca,非常像st表,詳見大白p345。

4、樹上差分。

其實我寫了那麼多就是想寫樹上差分啦。

二維差分是二維的動態規劃。

樹上差分就是樹形dp!!!(非常簡單的那種dp)。

比如想讓某條鏈[x,y](不妨設x的深度顯然如果不是一直往下的鏈一定可以拆成兩條一直往下的鏈,然後分別更新即可,需要用到lca。

最後o(n)離線就是樹形dp。dp[u]=∑dp[v](v是u的子節點)。

然後dp[u]就是單點的值啦。

codeforces 739b

**#includeusing namespace std;

typedef long long ll;

const ll maxn = 200010;

ll n;

ll a[maxn],f[maxn],b[maxn],ans[maxn],vis[maxn];

vectorg[maxn];

vectorw[maxn];

void read()

}ll cmp(const ll i,const ll j)

ll sum;

vectordi,id;

void add(ll x,ll y)

void dfs(ll u)

{ ll k=lower_bound(di.begin(),di.end(),a[u]-sum,cmp)-di.begin();

vis[u]=1;

if(k!=(ll)di.size()) add(id[k],u);

di.push_back(-sum);

id.push_back(u);

for(unsigned int i=0;i

關於遞迴的一些感悟

前些天筆試思科時碰到了一道c的遞迴題目,當時一直糾結在退出遞迴時,其輸出應該只有最後一次printf吧。好吧,我承認我真的很菜,不過我現在弄明白了,遞迴說白了就是自己呼叫自己,當遞迴深度條件不滿足時就退出了遞迴,關鍵點在於退出遞迴後的函式是如何返回的。其實我們可以把遞迴認為是幾個函式在一層層的呼叫,...

關於機器學習的一些感悟

1 通過機器的學習 大規模 資料庫 複雜的感測器和巧妙的演算法,來完成分散的任務 是人工智慧的最新定義。2 mit 實驗室的機械人專家 rodney brooks 提出,要以 具身智慧型 embodied intelligence 的方法來製造機械人。從這種方法出發,製造類人機械人不再是發展更複雜的...

關於結對程式設計的一些感悟

這次專案通過和同學的結對程式設計,對於結對程式設計有了一些自己的感悟。首先,作為駕駛員在 方面,自己原先編寫時會出現的很多格式不規範,不便於讀的地方都能得到糾正,而且對於一些方法的編寫,自己的思路可能不夠簡便,也能得到領航員的修改意見。其次,作為領航員時,能夠很好的鍛鍊自己的閱讀 的能力,同時理解駕...