Bzoj1455 罗马游戏

Time Limit: 5 Sec  Memory Limit: 64 MB
Submit: 1622  Solved: 679

Description

罗马皇帝很喜欢玩杀人游戏。 他的军队里面有n个人,每个人都是一个独立的团。最近举行了一次平面几何测试,每个人都得到了一个分数。 皇帝很喜欢平面几何,他对那些得分很低的人嗤之以鼻。他决定玩这样一个游戏。 它可以发两种命令: 1. Merger(i, j)。把i所在的团和j所在的团合并成一个团。如果i, j有一个人是死人,那么就忽略该命令。 2. Kill(i)。把i所在的团里面得分最低的人杀死。如果i这个人已经死了,这条命令就忽略。 皇帝希望他每发布一条kill命令,下面的将军就把被杀的人的分数报上来。(如果这条命令被忽略,那么就报0分)

Input

第一行一个整数n(1<=n<=1000000)。n表示士兵数,m表示总命令数。 第二行n个整数,其中第i个数表示编号为i的士兵的分数。(分数都是[0..10000]之间的整数) 第三行一个整数m(1<=m<=100000) 第3+i行描述第i条命令。命令为如下两种形式: 1. M i j 2. K i

Output

如果命令是Kill,对应的请输出被杀人的分数。(如果这个人不存在,就输出0)

Sample Input

5
100 90 66 99 10
7
M 1 5
K 1
K 1
M 2 3
M 3 4
K 5
K 4

Sample Output

10
100
0
66

HINT

部分数据如下 JudgeOnline/upload/201607/aa.rar

Source

 

左偏树(可并堆)模板题

第40行fa[x]=mge,是因为x所在并查集中可能有以x为father的点,如果不修改fa[x],会导致一部分点从集合中脱离出去。

 

 1 /*by SilverN*/
 2 #include<algorithm>
 3 #include<iostream>
 4 #include<cstring>
 5 #include<cstdio>
 6 #include<cmath>
 7 #include<vector>
 8 using namespace std;
 9 const int mxn=1000100;
10 int read(){
11     int x=0,f=1;char ch=getchar();
12     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
13     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
14     return x*f;
15 }
16 struct node{
17     int l,r;
18     int w;
19 }t[mxn];
20 int dep[mxn];
21 int n,m;
22 bool kd[mxn];
23 int fa[mxn];
24 int find(int x){
25     if(fa[x]==x)return x;
26     return fa[x]=find(fa[x]);
27 }
28 int mge(int x,int y){
29     if(x*y==0)return x+y;
30     if(t[x].w>t[y].w)swap(x,y);
31     t[x].r=mge(t[x].r,y);
32     if(dep[t[x].l]<dep[t[x].r])swap(t[x].l,t[x].r);
33     dep[x]=dep[t[x].r]+1;
34     return x;
35 }
36 int kill(int x){
37     if(kd[x])return 0;
38     x=find(x);
39     kd[x]=1;
40     fa[x]=mge(t[x].l,t[x].r);
41     fa[fa[x]]=fa[x];//
42     return t[x].w;
43 }
44 int main(){
45     int i,j;
46     n=read();
47     for(i=1;i<=n;i++){
48         t[i].w=read();
49         fa[i]=i;
50     }
51     dep[0]=-1;
52     m=read();
53     char op[5];int x,y;
54     for(i=1;i<=m;i++){
55         scanf("%s",op);
56         if(op[0]=='M'){
57             x=read();y=read();
58             if(kd[x] || kd[y])continue;
59             x=find(x);y=find(y);
60             if(x!=y) fa[x]=fa[y]=mge(x,y);
61         }
62         else{
63             x=read();
64             printf("%d\n",kill(x));
65         }
66     }
67     return 0;
68 }

 

本文为博主原创文章,转载请注明出处。
posted @ 2016-12-24 11:10  SilverNebula  阅读(161)  评论(0编辑  收藏  举报
AmazingCounters.com