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\n",ex+quan+w[a]); 143 } 144 void F2() 145 { 146 inin(a);a=h.find(a); 147 printf("%d\n",quan+w[a]); 148 } 149 void F3(){printf("%d\n",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 }