首页 > 其他 > 详细

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

时间:2016-09-02 00:33:24      阅读:196      评论:0      收藏:0      [点我收藏+]

【题目大意】

给出一些数和一些操作。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 }

 

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

原文:http://www.cnblogs.com/iiyiyi/p/5831674.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!