AT1219 歴史 研究(回滾莫隊模板)

2022-06-20 18:54:07 字數 1397 閱讀 9447

點此看題面

這種區間詢問的問題一般來說可以利用莫隊解決。

然而這道題求的是最大值,似乎普通莫隊就無法很好地實現刪除操作,因此就需要回滾莫隊這種黑科技。

考慮我們先暴力處理掉左端點和右端點在同乙個塊內的詢問(顯然這部分複雜度是\(o(n\sqrt n)\)的),然後對於剩餘的詢問把它扔到左端點對應塊的\(vector\)中。

然後,對於每乙個左端點對應塊,我們把其中的詢問按右端點從小到大排序。

對每個詢問,我們只要加入上個右端點和當前右端點之間的數,接著加入左端點到塊的右邊界的所有數,並在詢問結束後撤銷左端點到塊的右邊界的修改。

分析複雜度,對於乙個塊,右端點只會單調右移,總複雜度\(o(n\sqrt n)\);對於每個左端點,到所在塊的右邊界最多只有\(o(\sqrt n)\)個數,總複雜度也是\(o(n\sqrt n)\)。

因此,回滾莫隊的複雜度依然是\(o(n\sqrt n)\)的!

加入乙個數直接修改計數陣列並更新答案即可。

而考慮撤銷,只要在加入需要撤銷的數(左端點到塊的右邊界的所有數)之前記錄下原先的答案,在撤銷時改回答案並直接修改計數陣列撤銷即可。

應該算是一道比較板子的題目了吧。

#include#define tp template#define ts template#define reg register

#define ri reg int

#define con const

#define ci con int&

#define i inline

#define w while

#define n 100000

#define sn 320

#define ll long long

using namespace std;

int n,qt,a[n+5],dc,dv[n+5],sz,bl[n+5];ll ans[n+5];struct q

i bool operator < (con q& o) con

tp i void read(ty& x)

ts i void read(ty& x,ar&... y)

tp i void writeln(ty x)

}using namespace fastio;

namespace rollbackmo//回滾莫隊

i void d(ci x) //加入;撤銷

i ll bf(ci l,ci r) //修改,並在詢問後撤銷

}using namespace rollbackmo;

int main()

//單調移動右端點,暴力做左端點

for(i=1;i<=qt;++i) writeln(ans[i]);return clear(),0;

}

AT1219 歴史 研究 回滾莫隊

題目描述見鏈結 直接使用莫隊,但是這道題目刪除時不好尋找次大值,考慮回滾莫隊,回滾莫隊的處理方式與莫隊大致是相同的,具體來說 對兩個相鄰的詢問區間 l r l,r l r l,r l r l r 若 b k id l bk id r bk id l bk id r bk id l b k id r ...

回滾莫隊 AT1219 歴史 研究

洛谷題目 at1219 不滿足區間減性質的運算,如最值,就不能用普通莫隊求,考慮回滾莫隊,它的核心思想就是若區間在塊內直接暴力,否則將右端點從小到大排序,右端點按普通莫隊求,那麼左端點由於只在乙個塊內,所以詢問完跳到塊末,由於塊的大小為根號,影響複雜度的實際上是右端點,然後每次處理完相同左端點塊清除...

題解 AT1219 歴史 研究

簡單分析 題面含有ioi 驚 可知此題是ioi 數字三角形 難度 逃 當然很多人都是抱著學回滾莫隊的目標來看這道題的,所以這裡介紹一下回滾莫隊。1 按莫隊的思路講詢問排序。2 查詢時列舉每個區間,我們需要保證右端點是保持單調遞增的,同時左端點每次在乙個塊中移動,以此來計算每個詢問的值。3 每一次到下...