bzoj2333 [SCOI2011]棘手的操作

题目链接

恶心的可并堆套可并堆

我之前天真地以为直接并查集可搞

经过一下午DEBUG,完成之后,发现无法处理负数QAQ

于是喊冬哥给我开了一波车,帮助我两个小时打完了可并堆套可并堆并AC啦QAQ

  1 #include<algorithm>
  2 #include<iostream>
  3 #include<cstdlib>
  4 #include<cstring>
  5 #include<cstdio>
  6 #include<string>
  7 #include<cmath>
  8 #include<ctime>
  9 #include<queue>
 10 #include<stack>
 11 #include<map>
 12 #include<set>
 13 #define rre(i,r,l) for(int i=(r);i>=(l);i--)
 14 #define re(i,l,r) for(int i=(l);i<=(r);i++)
 15 #define Clear(a,b) memset(a,b,sizeof(a))
 16 #define inout(x) printf("%d",(x))
 17 #define douin(x) scanf("%lf",&x)
 18 #define strin(x) scanf("%s",(x))
 19 #define LLin(x) scanf("%lld",&x)
 20 #define op operator
 21 #define CSC main
 22 typedef unsigned long long ULL;
 23 typedef const int cint;
 24 typedef long long LL;
 25 using namespace std;
 26 void inin(int &ret)
 27 {
 28     ret=0;int f=0;char ch=getchar();
 29     while(ch<'0'||ch>'9'){if(ch=='-')f=1;ch=getchar();}
 30     while(ch>='0'&&ch<='9')ret*=10,ret+=ch-'0',ch=getchar();
 31     ret=f?-ret:ret;
 32 }
 33 int quan,w[300030];
 34 int sta[300030],top;
 35 struct heap
 36 {
 37     int ch[300030][2],fa[300030],tag[300030];
 38     void down(int k)
 39     {
 40         if(!tag[k])return ;
 41         w[ch[k][0]]+=tag[k];
 42         w[ch[k][1]]+=tag[k];
 43         tag[ch[k][0]]+=tag[k];
 44         tag[ch[k][1]]+=tag[k];
 45         tag[k]=0;
 46     }
 47     int merge(int l,int r)
 48     {
 49         if(!l||!r)return l+r;
 50         if(w[l]<w[r])swap(l,r);
 51         down(l);
 52         ch[l][1]=merge(ch[l][1],r);
 53         fa[ch[l][1]]=l;
 54         swap(ch[l][0],ch[l][1]);
 55         return l;
 56     }
 57     int pop(int x)
 58     {
 59         down(x);
 60         int f=fa[x];
 61         int d=ch[f][1]==x;
 62         ch[f][d]=merge(ch[x][0],ch[x][1]);
 63         fa[ch[f][d]]=f;
 64         fa[x]=ch[x][0]=ch[x][1]=0;
 65         return find(ch[f][d]);
 66     }
 67     int find(int x){return !fa[x]?x:find(fa[x]);}
 68     void add(int k,int x)
 69     {
 70         top=0;
 71         int kk=k;
 72         while(fa[kk])kk=fa[kk],sta[++top]=kk;
 73         rre(i,top,1)down(sta[i]);
 74         int ff=pop(k);
 75         w[k]+=x;
 76         merge(k,ff);
 77     }
 78 }h;
 79 int root;
 80 int ch[300030][2],fa[300030];
 81 int merge(int l,int r)
 82 {
 83     if(!l||!r)return l+r;
 84     if(w[l]<w[r])swap(l,r);
 85     ch[l][1]=merge(ch[l][1],r);
 86     fa[ch[l][1]]=l;
 87     swap(ch[l][0],ch[l][1]);
 88     return l;
 89 }
 90 void pop(int x)
 91 {
 92     int f=fa[x];
 93     int d=ch[f][1]==x;
 94     ch[f][d]=merge(ch[x][0],ch[x][1]);
 95     fa[ch[f][d]]=f;
 96     ch[x][0]=ch[x][1]=fa[x]=0;
 97     if(root==x)root=ch[f][d];
 98 }
 99 int find(int x){return !fa[x]?x:find(fa[x]);}
100 int a,b;
101 void add(int k,int x)
102 {
103     pop(k);
104     w[k]+=x;
105     root=merge(k,root);
106 }
107 int n,m;
108 void U()
109 {
110     inin(a),inin(b);
111     if(a==b)return ;
112     a=h.find(a),b=h.find(b);
113     if(a==b)return ;
114     int hh=h.merge(a,b);
115     if(hh==a)pop(b);
116     else pop(a); 
117 }
118 void A1()
119 {
120     inin(a),inin(b);
121     int yuan=h.find(a);
122     h.add(a,b);int xian=h.find(a); 
123     if(yuan!=xian||!h.fa[a])
124     {
125         pop(yuan);
126         root=merge(xian,root);
127     }
128 }
129 void A2()
130 {
131     inin(a),inin(b);
132     a=h.find(a);
133     h.tag[a]+=b;w[a]+=b;
134     pop(a),root=merge(root,a);
135 }
136 void A3(){inin(a);quan+=a;}
137 void F1()
138 {
139     inin(a);int ex=0;int aa=a;
140     while(h.fa[aa])
141         aa=h.fa[aa],ex+=h.tag[aa];
142     printf("%d
",ex+quan+w[a]);
143 }
144 void F2()
145 {
146     inin(a);a=h.find(a);
147     printf("%d
",quan+w[a]);
148 }
149 void F3(){printf("%d
",quan+w[root]);}
150 int CSC()
151 {
152     inin(n);
153     re(i,1,n)inin(w[i]);
154     root=1;
155     re(i,2,n)root=merge(root,i);
156     inin(m);
157     re(i,1,m)
158     {
159         char s[5];
160         strin(s);
161         switch(s[0])
162         {
163             case 'U':U();break;
164             case 'A':
165                 switch(s[1])
166                 {
167                     case '1':A1();break;
168                     case '2':A2();break;
169                     case '3':A3();break;
170                 }break;
171             case 'F':
172                 switch(s[1])
173                 {
174                     case '1':F1();break;
175                     case '2':F2();break;
176                     case '3':F3();break;
177                 }
178         }
179     }
180     return 0;
181 }
原文地址:https://www.cnblogs.com/HugeGun/p/5208047.html