【裸裸的左偏树】BZOJ1455-罗马游戏

【题目大意】

给出一些数和一些操作。M:合并两个数所在的集合,如果有任意一个数被删除则忽略操作;K:删除某个数所在集合中最小的数。

【思路】

裸裸的,复习^ ^

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 using namespace std;
  6 const int MAXN=1000000+500;
  7 struct node
  8 {
  9     int key,dis,del;
 10     int lson,rson,father;
 11 }ltree[MAXN];
 12 int n,m;
 13
 14 int find(int a)
 15 {
 16     while (ltree[a].father!=a) a=ltree[a].father;
 17     return a;
 18 }
 19
 20 void build(int rt,int val)
 21 {
 22     ltree[rt].key=val;
 23     ltree[rt].dis=(rt==0)?-1:0;
 24     ltree[rt].del=0;
 25     ltree[rt].lson=ltree[rt].rson=0;
 26     ltree[rt].father=rt;
 27 }
 28
 29 int merge(int x,int y)
 30 {
 31     if (x==0||y==0) return (x|y);
 32     if (ltree[x].key>ltree[y].key) swap(x,y);
 33     ltree[x].rson=merge(ltree[x].rson,y);
 34     int &l=ltree[x].lson,&r=ltree[x].rson;
 35     ltree[l].father=ltree[r].father=x;
 36     if (ltree[l].dis<ltree[r].dis) swap(l,r);
 37     if (r==0) ltree[x].dis=0;
 38         else ltree[x].dis=ltree[r].dis+1;
 39     return x;
 40 }
 41
 42 void Del(int rt)
 43 {
 44     int l=ltree[rt].lson,r=ltree[rt].rson;
 45     ltree[l].father=l;
 46     ltree[r].father=r;
 47     ltree[rt].dis=ltree[rt].lson=ltree[rt].rson=0;
 48     ltree[rt].del=1;
 49     merge(l,r);
 50 }
 51
 52 void init()
 53 {
 54     scanf("%d",&n);
 55     for (int i=1;i<=n;i++)
 56     {
 57         int score;
 58         scanf("%d",&score);
 59         build(i,score);
 60     }
 61     build(0,0);
 62 }
 63
 64 void solve()
 65 {
 66     scanf("%d",&m);
 67     for (int i=0;i<m;i++)
 68     {
 69         char op[1];
 70         scanf("%s",op);
 71         if (op[0]==‘M‘)
 72         {
 73             int a,b;
 74             scanf("%d%d",&a,&b);
 75             if (!ltree[a].del&&!ltree[b].del)
 76             {
 77                 int fa=find(a),fb=find(b);
 78                 if (fa!=fb) merge(fa,fb);//不要忘记要判断两者不在同一个集合中
 79             }
 80         }
 81         if (op[0]==‘K‘)
 82         {
 83             int a;
 84             scanf("%d",&a);
 85             if (ltree[a].del) puts("0");
 86                 else
 87                 {
 88                     int fa=find(a);
 89                     printf("%d\n",ltree[fa].key);
 90                     Del(fa);
 91                 }
 92         }
 93     }
 94 }
 95
 96 int main()
 97 {
 98     init();
 99     solve();
100     return 0;
101 }
时间: 2024-08-09 20:50:13

【裸裸的左偏树】BZOJ1455-罗马游戏的相关文章

C++之路进阶——左偏堆(罗马游戏)

F.A.Qs Home Discuss ProblemSet Status Ranklist Contest ModifyUser  gryz2016 Logout 捐赠本站 Notice:由于本OJ建立在Linux平台下,而许多题的数据在Windows下制作,请注意输入.输出语句及数据类型及范围,避免无谓的RE出现. 1455: 罗马游戏 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1061  Solved: 439[Submit][Status

[BZOJ 1455]罗马游戏(左偏树+并查集)

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

[BZOJ1455]罗马游戏-斜堆/左偏树-并查集(+数据生成器)

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

[BZOJ1455] 罗马游戏|左偏树

1455: 罗马游戏 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 870  Solved: 347[Submit][Status][Discuss] Description 罗马皇帝很喜欢玩杀人游戏. 他的军队里面有n个人,每个人都是一个独立的团.最近举行了一次平面几何测试,每个人都得到了一个分数. 皇帝很喜欢平面几何,他对那些得分很低的人嗤之以鼻.他决定玩这样一个游戏. 它可以发两种命令: 1. Merger(i, j).把i所在的团和j所在的团

【BZOJ-1455】罗马游戏 可并堆 (左偏树)

1455: 罗马游戏 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1355  Solved: 561[Submit][Status][Discuss] Description 罗马皇帝很喜欢玩杀人游戏. 他的军队里面有n个人,每个人都是一个独立的团.最近举行了一次平面几何测试,每个人都得到了一个分数. 皇帝很喜欢平面几何,他对那些得分很低的人嗤之以鼻.他决定玩这样一个游戏. 它可以发两种命令: 1. Merger(i, j).把i所在的团和j所在的

[bzoj1455]罗马游戏_左偏树_并查集

罗马游戏 bzoj-1455 题目大意:给你n个人,2种操作,m次操作:1.将i号士兵所在的集合的最小值删除 2.合并i和j两个士兵所在的团体 注释:$1\le n\le 10^6$,$1\le m \le 10^5$. 想法:又是GXZlegend讲课,可并堆中的左偏树.了解一下: 一个具有堆性质的二叉树满足任意一个节点x中,dis[lson[x]]>=dis[rson[x]],其中,dis表示当前节点一直走右儿子的最长步数.合并是递归合并,我们通过递归处理一两个节点为根节点的左偏树的合并,显

【BZOJ 1455】 1455: 罗马游戏 (可并堆-左偏树+并查集)

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

BZOJ 1455 罗马游戏 左偏树

题目大意:给定n个点,每个点有一个权值,提供两种操作: 1.将两个点所在集合合并 2.将一个点所在集合的最小的点删除并输出权值 很裸的可并堆 n<=100W 启发式合并不用想了 左偏树就是快啊~ #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define M 1001001 using namespace std; struct abcd{ abcd

bzoj 1455: 罗马游戏 左偏树+并查集

1455: 罗马游戏 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 668  Solved: 247[Submit][Status] Description 罗马皇帝很喜欢玩杀人游戏. 他的军队里面有n个人,每个人都是一个独立的团.最近举行了一次平面几何测试,每个人都得到了一个分数. 皇帝很喜欢平面几何,他对那些得分很低的人嗤之以鼻.他决定玩这样一个游戏. 它可以发两种命令: 1. Merger(i, j).把i所在的团和j所在的团合并成一个团.如果

【左偏树】HDU1512-Monkey King

[题目大意] 在一个森林里住着N(N<=10000)只猴子.在一开始,他们是互不认识的.但是随着时间的推移,猴子们少不了争斗,但那只会发生在互不认识(认识具有传递性)的两只猴子之间.争斗时,两只猴子都会请出他认识的猴子里最强壮的一只(有可能是他自己)进行争斗.争斗后,这两只猴子就互相认识.每个猴子有一个强壮值,但是被请出来的那两只猴子进行争斗后,他们的强壮值都会减半(例如10会减为5,5会减为2).现给出每个猴子的初始强壮值,给出M次争斗,如果争斗的两只猴子不认识,那么输出争斗后两只猴子的认识的