bzoj2333 SCOI2011 棘手的操作

2022-05-21 13:39:09 字數 1179 閱讀 8890

(題目鏈結)

n個節點維護一些操作。。

我們用可並大根堆進行維護。

對於每個連通塊建乙個區域性可並堆,因為要詢問全域性最大值,所以還要對全域性建乙個全域性可並堆記錄之前區域性可並堆堆頂元素。

u:合併x所在的堆以及y所在的堆,並在全域性堆中刪除合併前的區域性堆堆頂元素,因為它合併以後已經不是其連通塊的堆頂了。

a1:在堆中刪除,更新後再加入堆

a2:找到其堆頂,對堆頂進行修改並打上標記

a3:對全域性都打個標記即可

f1:將標記下傳後輸出

f2:找到其所在的堆頂輸出

f3:輸出全域性堆的堆頂

upd:這個做法被×了,暴力找堆頂複雜度不對,得寫啟發式合併或者線段樹,右轉lcf。。當然拿來練練手也是可以的,反正能過資料

碼農題就是細節多

// bzoj2333

#include#include#include#include#include#include#include#define ll long long

#define inf 1<<30

#define pi acos(-1.0)

#define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);

using namespace std;

const int maxn=300010;

struct heap q[maxn],qq[maxn];

int n,m,rt,tag;

char op[10];

void pushdown(heap *q,int k)

int merge(heap *q,int x,int y)

return q.front();

}void newq(heap *q,int x,int val)

int main()

} if (op[0]=='a')

if (op[1]=='2')

if (op[1]=='3') scanf("%d",&y),tag+=y;

} if (op[0]=='f')

if (op[1]=='2')

if (op[1]=='3') printf("%d\n",qq[rt].val+tag);

} }return 0;

}

bzoj2333 SCOI2011 棘手的操作

全抄hzwer的 但是有幾個點還是說一下 首先,如果兩個點已經在乙個堆裡面了,再合併會出現環 這個很顯然把,但是你會忘了寫 其次,系統棧會炸 include include include include using namespace std multisetst struct heapq 300...

bzoj2333 SCOI2011 棘手的操作

可以大力寫乙個平衡樹啟發式合併,除了每個連通塊維護乙個平衡樹再對全域性維護乙個平衡樹,每個節點表示某乙個連通塊的最大值.我的常數比較大,危險地卡過去了.include include include using namespace std const int maxn 300005 struct n...

bzoj2333 SCOI2011 棘手的操作

bzoj2333 聯通塊合後並不需要再拆開,可以考慮離線做法 想辦法將各個點按聯通塊有序排列,接下來就直接用線段樹區間維護即可 fa i 記錄 i 所處聯通塊的起始點 ed i 記錄以i為起始點的聯通塊的終止點 nt i 記錄 i 的下乙個節點 include using namespace std...