P3168 CQOI2015 任務查詢系統

2022-04-12 05:42:37 字數 1387 閱讀 2105

「p3168 [cqoi2015]任務查詢系統」--傳送門

給你\(m\)條資訊,即乙個優先順序為\(p_i\)的任務,處理時間為\(l_i~r_i\)。

給你\(n\)條詢問,每條詢問:在\(x\)時刻優先順序前\(k\)小的任務\(p\)的總和為多少。

\(1<=n,m<=10^5,1<=p_i<=10^7\)

\(n,m\)這樣的範圍,大概是\(o(nlogn)\)吧,並且有前\(k\)小,而且是對於乙個序列的操作,同時他問的是\(x\)時刻,所以我們要知道每乙個時刻樹的版本,為了節省記憶體,要用可持久化線段樹去維護值域

我們可以將每一時刻作為乙個版本,每乙個版本的樹中包含這一時刻正在進行的任務及其優先順序

我們可以用差分的思想,若乙個優先順序為\(p_i\)的任務在\([l,r]\)區間內執行,我們就可以在\(l\)版本時加上數\(p_i\),\(l~r\)版本之間不動它,使其依次向後承接/轉移,到了\(r+1\)版本將其刪除即可。

對於乙個版本,我們用主席樹維護值域區間\([1,10^7]\),也就是優先順序的值域,從而在求前\(k\)小的時候能夠二分確定位置。可以離散化,但我懶得寫了。

我們對於樹上節點不僅要維護乙個\(size\)從而確定前\(k\)小的範圍,還要維護乙個\(val\)去求和,每次向該節點及其子節點(如果不是葉子節點)加數的時候,\(val\)都要加上該數的值,刪除的話就減去,我們這樣就可以用該節點的\(val\)來表示出該節點所代表範圍中所有加過數的總和,從而更方便的求出前\(k\)小的和。

查詢也跟平時的主席樹一樣,只不過是個求和而已。

注意細節,訪問到葉子節點時,該葉子節點可能size>1,但不選他就不夠k個,選他就超過k個,我們要用val/size*k去選出k個。

注意判斷:除數不為0。

#include #include #define int long long

using namespace std;

const int maxn=100000+5;

struct node;

node t[maxn*25*2];

int n,m;

int pre=1;

vectora[maxn],b[maxn];//對每個時間點開vector

int root[maxn];

int tot;

void insert(int &rt,int l,int r,int p,int v)

int q(int rt,int l,int r,int k)

signed main()

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

for(int i=1,x,a,b,c;i<=n;++i)

return 0;

}

P3168 CQOI2015 任務查詢系統

最近實驗室正在為其管理的超級計算機編制一套任務管理系統,而你被安排完成其中的查詢部分。超級計算機中的任務用三元組 si,ei,pi 描述,si,ei,pi 表示任務從第si秒開始,在第ei秒後結束 第si秒和ei秒任務也在執行 其優先順序為pi。同一時間可能有多個任務同時執行,它們的優先順序可能相同...

P3168 CQOI2015 任務查詢系統

最近實驗室正在為其管理的超級計算機編制一套任務管理系統,而你被安排完成其中的查詢部分。超級計算機中的任務用三元組 si,ei,pi 描述,si,ei,pi 表示任務從第si秒開始,在第ei秒後結束 第si秒和ei秒任務也在執行 其優先順序為pi。同一時間可能有多個任務同時執行,它們的優先順序可能相同...

P3168 CQOI2015 任務查詢系統

傳送門 求前 k 小的數的和,考慮主席樹 但是如果每個時間都暴力插入顯然會gg 發現每個任務都是區間,查詢是單點查詢 所以考慮維護差分陣列 直接用主席樹維護差分陣列,因為同一時間差分可能有多次修改,所以要把當前修改全部搞完才算當前時間的線段樹 詢問就在相應時間點的線段樹上走 具體看 理解吧 incl...