1. 程式人生 > >[Bzoj5179][Jsoi2011]任務調度(左偏樹)

[Bzoj5179][Jsoi2011]任務調度(左偏樹)

sam lin ont class ems 整型 pri ans ==

5179: [Jsoi2011]任務調度


Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 5 Solved: 4
[Submit][Status][Discuss]

Description


一臺超級計算機共有N顆CPU。現在這臺超級計算機有M個任務要做,但同時還要考慮到不能讓CPU過熱。所幸的是這 臺超級計算機已經將任務安排好了,現在要做的只是請你根據安排好的指令來模擬它的工作過程。一開始,這N顆C PU都沒有被分配任何的任務。之後,會給你以下幾類指令(CPU的編號為1到N的整數,任務的編號為1到M的整數) 指令格式 作用 ADD n k w 將 k 號任務(權值為 w)分配給 n 號 CPU DEC n k w 將 k 號任務的權值減少 w(已知 k 號任務被分配給了 n 號 CPU) TRANS n1 n2 將分配給 n1 號 CPU 的任務全部轉移給 n2 號 CPU MIN n 輸出分配給 n 號 CPU 的任務中權值最小的任務的權值 WORK n w 將分配給 n 號 CPU 的任務中權值最小的任務的權值加上 w, 如果權值最小的任務不唯一,則不更改權值,並輸出一行“ ERROR”

Input


包含N+1行。 第1行包含三個正整數N、M、K,分別表示CPU的數目、任務數和指令數。 第2行到N+1行,每行包含一條指令。 N≤500, M≤300000, K≤300000。 保證任務的權值在 32 位有符號整型的範圍內。 保證一個任務只會被分配一次(即至多被 ADD 一次)。 保證 ADD 指令、DEC 指令和 WORK 指令中的 w 是非負整數。 保證 TRANS 指令的兩個參數不相同。

Output


若幹行,其中包括MIN語句的輸出和“ERROR”輸出,每個輸出占一行

Sample Input


2 3 13
ADD 1 2 100
ADD 1 1 90
MIN 1
WORK 1 20
TRANS 1 2
MIN 2
ADD 1 3 105
TRANS 2 1
MIN 1
DEC 1 3 200
MIN 1
DEC 1 1 205
WORK 1 15

Sample Output


90
100
100
-95
ERROR

分析:


裸裸的可並堆題,用左偏樹亂搞即可

代碼:


# include <iostream>
# include 
<cstdio> # include <algorithm> using namespace std; const int N = 3e5 + 12; int d[512],n,m,k; struct node{ int w,d,lc,rc,fa; }t[N]; int merge(int x,int y) { if(!x)return y; if(!y)return x; if(t[x].w > t[y].w)swap(x,y); t[x].rc = merge(t[x].rc,y); t[t[x].rc].fa = x; if(t[t[x].rc].d > t[t[x].lc].d)swap(t[x].rc,t[x].lc); t[x].d = t[t[x].rc].d + 1; return x; } void erase(int x,int y,int z) { int u = merge(t[y].lc,t[y].rc),g = t[y].fa; if(d[x] == y)d[x] = u; if(t[g].lc == y)t[g].lc = u; else if(t[g].rc == y)t[g].rc = u; t[u].fa = g;t[y].lc = t[y].rc = t[y].fa = t[y].d = 0; t[y].w += z; d[x] = merge(d[x],y); } int main() { scanf("%d %d %d",&n,&m,&k);char ch[5];int x,y,z; while(k--) { scanf("%s",ch); if(ch[0] == A) { scanf("%d %d %d",&x,&y,&z); t[y].w = z; d[x] = merge(d[x],y); } if(ch[0] == D) { scanf("%d %d %d",&x,&y,&z); erase(x,y,-z); } if(ch[0] == T) { scanf("%d %d",&x,&y); d[y] = merge(d[x],d[y]); d[x] = 0; } if(ch[0] == M) { scanf("%d",&x); printf("%d\n",t[d[x]].w); } if(ch[0] == W) { scanf("%d %d",&x,&y); bool flag = true;int l = t[d[x]].lc,r = t[d[x]].rc; if(l && t[l].w == t[d[x]].w)flag = false; if(r && t[r].w == t[d[x]].w)flag = false; if(flag)erase(x,d[x],y); else puts("ERROR"); } } }

[Bzoj5179][Jsoi2011]任務調度(左偏樹)