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 }

 

posted @ 2019-02-25 14:56  guapisolo  阅读(123)  评论(0编辑  收藏  举报