CQOI 2015 任務查詢系統

2022-04-30 07:48:11 字數 1298 閱讀 1694

給定\(m\)個任務\((l,r,p)\),其中\((l,r)\)代表這個任務將於時間\([l,r]\)內進行,而\(p\)代表的是這個任務的優先順序

有\(n\)個詢問\((x,k)\),每次詢問在時間點\(x\)進行的所有任務按優先順序從小到大排序,前\(k\)個任務的優先順序之和

求前\(k\)個數的和,我們想到主席樹

區間覆蓋問題,我們想到差分

眾所周知主席樹運用了字首和的思想,那麼當然也可以進行差分

那麼這道題就是愉快的差分\(+\)主席樹了

把乙個任務的\((l,r)\)端點拆開,第\(l\)顆主席樹的\(p\)位置加一,在第\(r+1\)顆主席樹的\(p\)位置減一

排序以後逐個加入,實際上就相當於在差分陣列上求字首和。具體實現上不用排序,會有點麻煩:用\(vector\)儲存即可

每次查詢第\(x\)顆主席樹的前\(k\)個元素之和即可

但是我們會發現乙個問題:如果在同乙個位置我們進行了多次新增,此時主席樹的根的標號與其所在的字首可能是不對應的

記錄乙個\(id\)代表每個字首對應的實際根的編號即可

#include #include #include using namespace std;

#define int long long

#define pii pair#define x first

#define y second

void fast_io();

const int n = 2e5 + 10;

int n, m, t;

int it, rhs, lstans = 1;

int s[n], id[n], rt[n];

vectorvec[n];

struct ctree

int newnode()

void mkchain(int &x, int y, int l, int r, int k, int v)

int query(int x, int l, int r, int k)

} tr;

void discre()

main()

discre();

for (int i = 1; i <= rhs; ++i)

int sz = vec[i].size();

id[i] = it + sz;

for (int j = 0; j < sz; ++j) }

for (int i = 1; i <= m; ++i)

return 0;

}void fast_io()

CQOI2015 任務查詢系統

因為對於任務來說,對一段區間是有用的,於是我們可以用差分來表示區間,然後主席樹維護字首區間和即可。然後因為我們是求和,我們同時主席樹也要維護區間的數字個數,因為求k小和。但是有可能當前區間的有a個相同的數字,我們求b個和,然後bac pragma gcc optimize 2 include def...

CQOI2015 任務查詢系統

主席樹維護k大,考慮到利用主席樹字首和的性質。把每個任務拆分成權值為1的進入操作,和權值為 1的退出操作 注意因為是閉區間,所以右邊的位置加進去的時候需要 1 應該是個動態開點的權值線段樹一樣的東西吧 維護v,表示該節點維護的任務數量是多少。sum表示該節點維護的任務總和是多少。輸出k大的時候 因為...

CQOI2015 任務查詢系統

time limit 20 sec memory limit 512 mb submit 3352 solved 1072 submit status discuss 最近實驗室正在為其管理的超級計算機編制一套任務管理系統,而你被安排完成其中的查詢部分。超級計算機中的 任務用三元組 si,ei,pi...