zoukankan      html  css  js  c++  java
  • BZOJ2329: [HNOI2011]括号修复(Splay)

    解题思路:

     Replace、Swap、Invert都可以使用Splay完美解决(只需要解决一下标记冲突就好了)。

    最后只需要统计左右括号冲突就好了。

    相当于动态统计最大前缀合和最小后缀和。

    因为支持翻转反转操作,翻转标记或取反就好了。

    代码:

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 #define lll tr[spc].ch[0]
      5 #define rrr tr[spc].ch[1]
      6 #define ls ch[0]
      7 #define rs ch[1]
      8 typedef long long lnt;
      9 const int N=300000;
     10 struct trnt{
     11     int ch[2];
     12     int fa;
     13     int wgt;
     14     int val;
     15     int sum;
     16     int mxp;
     17     int mnp;
     18     int mxs;
     19     int mns;
     20     int lzt;
     21     bool rev;
     22     bool ant;
     23 }tr[N];
     24 int n,m;
     25 int siz;
     26 int root;
     27 int num[N];
     28 char cmd[N];
     29 bool whc(int spc)
     30 {
     31     return tr[tr[spc].fa].rs==spc;
     32 }
     33 void pushup(int spc)
     34 {
     35     tr[spc].wgt=1;
     36     if(lll)
     37         tr[spc].wgt+=tr[lll].wgt;
     38     if(rrr)
     39         tr[spc].wgt+=tr[rrr].wgt;
     40     tr[spc].sum=tr[spc].val;
     41     if(lll)
     42         tr[spc].sum+=tr[lll].sum;
     43     if(rrr)
     44         tr[spc].sum+=tr[rrr].sum;
     45     tr[spc].mxp=tr[spc].mxs=std::max(tr[spc].sum,0);
     46     tr[spc].mnp=tr[spc].mns=std::min(0,tr[spc].sum);
     47     if(lll)
     48     {
     49         tr[spc].mxp=std::max(tr[spc].mxp,std::max(tr[lll].mxp,tr[lll].sum+tr[spc].val));
     50         tr[spc].mnp=std::min(tr[spc].mnp,std::min(tr[lll].mnp,tr[lll].sum+tr[spc].val));
     51         tr[spc].mxs=std::max(tr[spc].mxs,std::max(tr[rrr].sum+tr[spc].val,tr[spc].val+tr[lll].mxs+tr[rrr].sum));
     52         tr[spc].mns=std::min(tr[spc].mns,std::min(tr[rrr].sum+tr[spc].val,tr[spc].val+tr[lll].mns+tr[rrr].sum));
     53     }
     54     if(rrr)
     55     {
     56         tr[spc].mxs=std::max(tr[spc].mxs,std::max(tr[rrr].mxs,tr[rrr].sum+tr[spc].val));
     57         tr[spc].mns=std::min(tr[spc].mns,std::min(tr[rrr].mns,tr[rrr].sum+tr[spc].val));
     58         tr[spc].mxp=std::max(tr[spc].mxp,std::max(tr[lll].sum+tr[spc].val,tr[spc].val+tr[lll].sum+tr[rrr].mxp));
     59         tr[spc].mnp=std::min(tr[spc].mnp,std::min(tr[lll].sum+tr[spc].val,tr[spc].val+tr[lll].sum+tr[rrr].mnp));
     60     }
     61     return ;
     62 }
     63 void trr(int spc)
     64 {
     65     if(!spc)
     66         return ;
     67     std::swap(lll,rrr);
     68     std::swap(tr[spc].mxp,tr[spc].mxs);
     69     std::swap(tr[spc].mnp,tr[spc].mns);
     70     tr[spc].rev^=1;
     71     return ;
     72 }
     73 void anti(int spc)
     74 {
     75     if(!spc)
     76         return ;
     77     tr[spc].val*=-1;
     78     tr[spc].sum*=-1;
     79     tr[spc].mxp*=-1;
     80     tr[spc].mnp*=-1;
     81     tr[spc].mxs*=-1;
     82     tr[spc].mns*=-1;
     83     std::swap(tr[spc].mxp,tr[spc].mnp);
     84     std::swap(tr[spc].mxs,tr[spc].mns);
     85     tr[spc].ant^=1;
     86     return ;
     87 }
     88 void chg(int spc,int v)
     89 {
     90     if(!spc)
     91         return ;
     92     tr[spc].ant=false;
     93     tr[spc].val=v;
     94     tr[spc].lzt=v;
     95     tr[spc].sum=v*tr[spc].wgt;
     96     if(v==1)
     97     {
     98         tr[spc].mnp=0;
     99         tr[spc].mns=0;
    100         tr[spc].mxp=v*tr[spc].wgt;
    101         tr[spc].mxs=v*tr[spc].wgt;
    102     }else{
    103         tr[spc].mxp=0;
    104         tr[spc].mxs=0;
    105         tr[spc].mnp=v*tr[spc].wgt;
    106         tr[spc].mns=v*tr[spc].wgt;
    107     }
    108     return ;
    109 }
    110 void pushdown(int spc)
    111 {
    112     if(tr[spc].rev)
    113     {
    114         trr(lll);
    115         trr(rrr);
    116         tr[spc].rev=false;
    117     }
    118     if(tr[spc].lzt)
    119     {
    120         chg(lll,tr[spc].lzt);
    121         chg(rrr,tr[spc].lzt);
    122         tr[spc].lzt=0;
    123     }
    124     if(tr[spc].ant)
    125     {
    126         anti(lll);
    127         anti(rrr);
    128         tr[spc].ant=false;
    129     }
    130     return ;
    131 }
    132 void recal(int spc)
    133 {
    134     if(tr[spc].fa)
    135         recal(tr[spc].fa);
    136     pushdown(spc);
    137     return ;
    138 }
    139 void rotate(int spc)
    140 {
    141     int f=tr[spc].fa;
    142     bool k=whc(spc);
    143     tr[f].ch[k]=tr[spc].ch[!k];
    144     tr[spc].ch[!k]=f;
    145     tr[tr[f].fa].ch[whc(f)]=spc;
    146     tr[spc].fa=tr[f].fa;
    147     tr[f].fa=spc;
    148     tr[tr[f].ch[k]].fa=f;
    149     pushup(f);
    150     pushup(spc);
    151     return ;
    152 }
    153 void splay(int spc,int f)
    154 {
    155     recal(spc);
    156     while(tr[spc].fa!=f)
    157     {
    158         int ft=tr[spc].fa;
    159         if(tr[ft].fa==f)
    160         {
    161             rotate(spc);
    162             break;
    163         }
    164         if(whc(spc)^whc(ft))
    165             rotate(spc);
    166         else
    167             rotate(ft);
    168         rotate(spc);
    169     }
    170     if(!f)
    171         root=spc;
    172     return ;
    173 }
    174 void Build(int l,int r,int &spc,int f)
    175 {
    176     if(l>r)
    177         return ;
    178     int mid=(l+r)>>1;
    179     spc=++siz;
    180     tr[spc].val=num[mid];
    181     tr[spc].fa=f;
    182     Build(l,mid-1,lll,spc);
    183     Build(mid+1,r,rrr,spc);
    184     pushup(spc);
    185     return ;
    186 }
    187 int plc(int spc,int k)
    188 {
    189     pushdown(spc);
    190     if(tr[lll].wgt>=k)
    191         return plc(lll,k);
    192     if(tr[lll].wgt+1==k)
    193         return spc;
    194     return plc(rrr,k-tr[lll].wgt-1);
    195 }
    196 void rush(int l,int r)
    197 {
    198     l=plc(root,l);
    199     r=plc(root,r+2);
    200     splay(l,0);
    201     splay(r,root);
    202     return ;
    203 }
    204 int main()
    205 {
    206     scanf("%d%d",&n,&m);
    207     scanf("%s",cmd+1);
    208     for(int i=1;i<=n;i++)
    209         num[i]=((cmd[i]==')')<<1)-1;
    210     Build(0,n+1,root,0);
    211     while(m--)
    212     {
    213         int l,r;
    214         scanf("%s",cmd+1);
    215         scanf("%d%d",&l,&r);
    216         rush(l,r);
    217         if(cmd[1]=='R')
    218         {
    219             scanf("%s",cmd+1);
    220             chg(tr[tr[root].rs].ls,((cmd[1]==')')<<1)-1);
    221         }else if(cmd[1]=='S')
    222             trr(tr[tr[root].rs].ls);
    223         else if(cmd[1]=='I')
    224             anti(tr[tr[root].rs].ls);
    225         else{
    226             int spc=tr[tr[root].rs].ls;
    227             printf("%d
    ",(tr[spc].mxp+1)/2+(-tr[spc].mns+1)/2);
    228         }
    229         pushup(tr[root].rs);
    230         pushup(root);
    231     }
    232     return 0;
    233 }
  • 相关阅读:
    在maven工程中使用groovy
    groovy学习1搭建环境
    Android 中运行时权限获取联系人信息 Demo
    Android 拍照或相册选择照片进行显示缩放位图 Demo
    Android 热点相关操作
    Android 内嵌 HTML5 并进行交互
    AJAX实现局部刷新
    C#主要用于查询sql的web项目:查询以及页面显示数据非常缓慢的改进方案
    配置和读取web.config数据库
    web项目在服务器IIS7上的部署:达到内部网可以通过输入网页直接访问的效果
  • 原文地址:https://www.cnblogs.com/blog-Dr-J/p/10116235.html
Copyright © 2011-2022 走看看