标签:
2016-05-31 21:45:41
题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2333
(学习了黄学长的代码
有如下操作:
U x y: 加一条边,连接第x个节点和第y个节点
A1 x v: 将第x个节点的权值增加v
A2 x v: 将第x个节点所在的连通块的所有节点的权值都增加v
A3 v: 将所有节点的权值都增加v
F1 x: 输出第x个节点当前的权值
F2 x: 输出第x个节点所在的连通块中,权值最大的节点的权值
F3: 输出所有节点中,权值最大的节点的权值
U就是一个合并操作,用可并堆
A1将x点从所在堆中删去,修改权值后再加进去
A2的话在所在堆的堆顶上加tag
1 #include<bits/stdc++.h> 2 #define inf 1000000000 3 #define ll long long 4 #define N 300005 5 using namespace std; 6 int read(){ 7 int x=0,f=1;char ch=getchar(); 8 while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} 9 while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} 10 return x*f; 11 } 12 int n,Q,overadd,fa[N],tag[N],ls[N],rs[N],v[N],dep[N]; 13 multiset<int> st; 14 char ch[5]; 15 int find(int x){ 16 while(fa[x])x=fa[x]; 17 return x; 18 } 19 void pushdown(int x){ 20 if(!tag[x])return; 21 if(ls[x])tag[ls[x]]+=tag[x],v[ls[x]]+=tag[x]; 22 if(rs[x])tag[rs[x]]+=tag[x],v[rs[x]]+=tag[x]; 23 tag[x]=0; 24 } 25 int merge(int x,int y){ 26 if(!x||!y)return x+y; 27 if(v[x]<v[y])swap(x,y); 28 pushdown(x); 29 rs[x]=merge(rs[x],y); 30 fa[rs[x]]=x; 31 if(dep[ls[x]]<dep[rs[x]])swap(ls[x],rs[x]); 32 dep[x]=dep[rs[x]]+1; 33 return x; 34 } 35 void unite(int x,int y){ 36 int fx=find(x),fy=find(y); 37 if(fx!=fy){ 38 int t=merge(fx,fy); 39 if(t==fx)st.erase(st.find(v[fy])); 40 else st.erase(st.find(v[fx])); 41 } 42 } 43 void Pushdown(int x){ 44 if(fa[x])Pushdown(fa[x]); 45 pushdown(x); 46 } 47 int del(int x){ 48 int t=merge(ls[x],rs[x]),f=fa[x]; 49 ls[x]=rs[x]=fa[x]=0; 50 if(x==ls[f])ls[f]=t; 51 else rs[f]=t; 52 fa[t]=f; 53 return find(t); 54 } 55 void add(int x,int val){ 56 Pushdown(x); 57 st.erase(st.find(v[find(x)])); 58 v[x]+=val; 59 st.insert(v[merge(x,del(x))]); 60 } 61 void change(int x,int val){ 62 int f=find(x); 63 tag[f]+=val;v[f]+=val; 64 st.erase(st.find(v[f]-val));st.insert(v[f]); 65 } 66 void getval(int x){ 67 Pushdown(x); 68 printf("%d\n",v[x]+overadd); 69 } 70 int main(){ 71 n=read(); 72 for(int i=1;i<=n;i++)v[i]=read(),st.insert(v[i]); 73 Q=read(); 74 while(Q--){ 75 scanf("%s",ch); 76 if(ch[0]==‘A‘){ 77 if(ch[1]==‘1‘){ 78 int x=read(),y=read();add(x,y); 79 } 80 else if(ch[1]==‘2‘){ 81 int x=read(),y=read();change(x,y); 82 } 83 else overadd+=read(); 84 } 85 else if(ch[0]==‘F‘){ 86 if(ch[1]==‘1‘)getval(read()); 87 else if(ch[1]==‘2‘)getval(find(read())); 88 else printf("%d\n",*--st.find(inf)+overadd); 89 } 90 else{ 91 int x=read(),y=read();unite(x,y); 92 } 93 } 94 return 0; 95 }
【bzoj2333】 [SCOI2011]棘手的操作 可并堆+lazy标记
标签:
原文地址:http://www.cnblogs.com/wjyi/p/5547687.html