zoukankan      html  css  js  c++  java
  • 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
    ",h.queryx(x)+tot); break;
    123                 case '2': read(x), printf("%d
    ",h.querymax(x)+tot); break;
    124                 case '3': printf("%d
    ",(*s.begin()).x+tot); 
    125             }
    126         }
    127     }
    128     return 0;
    129 }
  • 相关阅读:
    [收藏转贴]struct探索·extern "C"含义探索 ·C++与C的混合编程·C 语言高效编程的几招
    [收藏转贴]构建RESTful风格的WCF服务
    [转贴] C/C++中动态链接库的创建和调用
    [转贴]WebService的简单实现 C++
    谷歌已经对Android的开源严防死守
    如何成为一名黑客?
    当程序员思路被打断
    编辑语言是这样的
    开发者需要掌握多少门语言?
    程序员的六大优势
  • 原文地址:https://www.cnblogs.com/guapisolo/p/10430913.html
Copyright © 2011-2022 走看看