1. 程式人生 > >[BZOJ 1455]羅馬遊戲(左偏樹+並查集)

[BZOJ 1455]羅馬遊戲(左偏樹+並查集)

node truct scrip logs wap find eap lib space

Description

羅馬皇帝很喜歡玩殺人遊戲。 他的軍隊裏面有n個人,每個人都是一個獨立的團。最近舉行了一次平面幾何測試,每個人都得到了一個分數。 皇帝很喜歡平面幾何,他對那些得分很低的人嗤之以鼻。他決定玩這樣一個遊戲。 它可以發兩種命令: 1. Merger(i, j)。把i所在的團和j所在的團合並成一個團。如果i, j有一個人是死人,那麽就忽略該命令。 2. Kill(i)。把i所在的團裏面得分最低的人殺死。如果i這個人已經死了,這條命令就忽略。 皇帝希望他每發布一條kill命令,下面的將軍就把被殺的人的分數報上來。(如果這條命令被忽略,那麽就報0分)

Solution

比較裸的一道左偏樹

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#define MAXN 1000005
using namespace std;
int n,m,father[MAXN];
bool die[MAXN];
struct Node
{
    int lch,rch,w,d;
    Node():lch(0),rch(0),w(0),d(0){}
}heap[MAXN];
int merge(int
x,int y) { if(!x||!y)return x+y; if(heap[x].w>heap[y].w)swap(x,y); heap[x].rch=merge(y,heap[x].rch); if(heap[heap[x].lch].d<heap[heap[x].rch].d)swap(heap[x].lch,heap[x].rch); heap[x].d=heap[heap[x].rch].d+1; return x; } int find(int x) { if(x==father[x])return
x; return father[x]=find(father[x]); } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&heap[i].w); father[i]=i;} scanf("%d",&m); for(int i=1;i<=m;i++) { char opt[3];int x,y; scanf("%s",opt); if(opt[0]==M) { scanf("%d%d",&x,&y); if(die[x]||die[y])continue; int fx=find(x),fy=find(y); if(fx!=fy) father[fx]=father[fy]=merge(fx,fy); } else { scanf("%d",&x); if(die[x])printf("0\n"); else { int fx=find(x); die[fx]=1; printf("%d\n",heap[fx].w); father[fx]=merge(heap[fx].lch,heap[fx].rch); father[father[fx]]=father[fx]; } } } return 0; }

[BZOJ 1455]羅馬遊戲(左偏樹+並查集)