BZOJ 2333 [SCOI2011]棘手的操作 (可并堆)
码农题..
很显然除了两个全局操作都能用可并堆完成
全局最大值用个multiset记录,每次合并时搞一搞就行了
注意使用multiset删除元素时
如果直接delete一个值,会把和这个值相同的所有元素全都删掉
如果find一个值得到一个迭代器,然后删除这个迭代器,就能只删除相同元素中的一个啦
因为这个调了1h..
1 #include <set> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #define N1 300010 6 using namespace std; 7 const int inf=0x3f3f3f3f; 8 9 template <typename _T> void read(_T &ret) 10 { 11 ret=0; _T fh=1; char c=getchar(); 12 while(c<'0'||c>'9'){ if(c=='-') fh=-1; c=getchar(); } 13 while(c>='0'&&c<='9'){ ret=ret*10+c-'0'; c=getchar(); } 14 ret=ret*fh; 15 } 16 struct node{ 17 int x; 18 node(int x):x(x){} node(){} 19 friend bool operator < (const node &s1,const node &s2) 20 { return s1.x>s2.x; } 21 }; 22 multiset<node>s; 23 24 struct Heap{ 25 #define ls ch[x][0] 26 #define rs ch[x][1] 27 int fa[N1],ch[N1][2],h[N1],val[N1],tag[N1],stk[N1],tp; 28 int idf(int x){ return ch[fa[x]][0]==x?0:1; } 29 void pushdown(int x) 30 { 31 if(!tag[x]) return; 32 val[ls]+=tag[x]; val[rs]+=tag[x]; 33 tag[ls]+=tag[x]; tag[rs]+=tag[x]; 34 tag[x]=0; 35 } 36 int merge(int x,int y) 37 { 38 if(!x||!y) return x+y; 39 if(val[x]<val[y]) swap(x,y); 40 pushdown(x); 41 ch[x][1]=merge(ch[x][1],y); 42 fa[ch[x][1]]=x; 43 if(h[ch[x][0]]<h[ch[x][1]]) 44 swap(ch[x][0],ch[x][1]); 45 h[x]=h[ch[x][1]]+1; 46 return x; 47 } 48 int findfa1(int x) 49 { 50 tp=0; stk[++tp]=x; 51 while(fa[x]) stk[++tp]=fa[x], x=fa[x]; 52 while(tp) pushdown(stk[tp--]); 53 return x; 54 } 55 int findfa2(int x) 56 { 57 while(fa[x]) x=fa[x]; 58 return x; 59 } 60 void uni(int x,int y) 61 { 62 x=findfa2(x), y=findfa2(y); if(x==y) return; 63 s.erase(node(val[x])), s.erase(node(val[y])); 64 x=merge(x,y); s.insert(node(val[x])); 65 } 66 void addx(int x,int w) 67 { 68 int y=findfa1(x),z; s.erase(node(val[y])); tp=0; 69 fa[ls]=fa[rs]=0; z=merge(ls,rs); ls=rs=0; 70 ch[fa[x]][idf(x)]=0; fa[x]=0; val[x]+=w; 71 z=merge(x,z); if(y!=x) z=merge(y,z); 72 s.insert(node(val[z])); 73 } 74 void addsome(int x,int w) 75 { 76 int y=findfa2(x); 77 s.erase(node(val[y])); 78 val[y]+=w; tag[y]+=w; 79 s.insert(node(val[y])); 80 } 81 int queryx(int x) 82 { 83 findfa1(x); 84 return val[x]; 85 } 86 int querymax(int x) 87 { 88 x=findfa2(x); 89 return val[x]; 90 } 91 #undef ls 92 #undef rs 93 }h; 94 int n,Q,de; 95 96 int main() 97 { 98 scanf("%d",&n); 99 int i,tot=0,x,y,cntf=0; char str[10]; 100 for(i=1;i<=n;i++) read(h.val[i]), s.insert(node(h.val[i])); 101 scanf("%d",&Q); 102 for(i=1;i<=Q;i++) 103 { 104 scanf("%s",str); 105 if(str[0]=='U') read(x), read(y), h.uni(x,y); 106 if(str[0]=='A') 107 { 108 switch(str[1]) 109 { 110 case '1': read(x), read(y); h.addx(x,y); break; 111 case '2': read(x), read(y), h.addsome(x,y); break; 112 case '3': read(y), tot+=y; break; 113 } 114 } 115 if(str[0]=='F') 116 { 117 cntf++; 118 if(cntf==107) 119 de=1; 120 switch(str[1]) 121 { 122 case '1': read(x), printf("%d\n",h.queryx(x)+tot); break; 123 case '2': read(x), printf("%d\n",h.querymax(x)+tot); break; 124 case '3': printf("%d\n",(*s.begin()).x+tot); 125 } 126 } 127 } 128 return 0; 129 }