• bzoj2209 [ JSOI2011 ] -- splay


    将左括号记为1,右括号记为-1,则一个合法的括号序列满足所有的前缀和非负。

    用splay维护。

    代码:

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 using namespace std;
      6 #define N 100010
      7 inline char nc(){
      8     static char buf[100000],*p1=buf,*p2=buf;
      9     if(p1==p2){
     10         p2=(p1=buf)+fread(buf,1,100000,stdin);
     11         if(p1==p2)return EOF;
     12     }
     13     return *p1++;
     14 }
     15 inline void Read(int& x){
     16     char c=nc();
     17     for(;c<'0'||c>'9';c=nc());
     18     for(x=0;c>='0'&&c<='9';x=(x<<3)+(x<<1)+c-48,c=nc());
     19 }
     20 char ss[30];
     21 int Len;
     22 inline void Print(int x){
     23     if(x==0)putchar(48);
     24     for(Len=0;x;x/=10)ss[++Len]=x%10;
     25     for(;Len;)putchar(ss[Len--]+48);putchar('
    ');
     26 }
     27 int i,j,k,n,m,s[N],ch[N][2],f[N],Rt,c1[N][2],c2[N][2],Sum[N],a[N],x,y,z;
     28 bool r[N],b[N];
     29 char S[N];
     30 inline int Min(int x,int y){
     31     return x<y?x:y;
     32 }
     33 inline int Max(int x,int y){
     34     return x<y?y:x;
     35 }
     36 inline int Abs(int x){
     37     return x<0?-x:x;
     38 }
     39 inline void Pushup(int x){
     40     s[x]=s[ch[x][0]]+s[ch[x][1]]+1;
     41     Sum[x]=Sum[ch[x][0]]+Sum[ch[x][1]]+a[x];
     42     c1[x][0]=Min(Sum[ch[x][0]]+a[x],Min(c1[ch[x][0]][0],Sum[ch[x][0]]+a[x]+c1[ch[x][1]][0]));
     43     c1[x][1]=Max(Sum[ch[x][0]]+a[x],Max(c1[ch[x][0]][1],Sum[ch[x][0]]+a[x]+c1[ch[x][1]][1]));
     44     c2[x][0]=Min(Sum[ch[x][1]]+a[x],Min(c2[ch[x][1]][0],Sum[ch[x][1]]+a[x]+c2[ch[x][0]][0]));
     45     c2[x][1]=Max(Sum[ch[x][1]]+a[x],Max(c2[ch[x][1]][1],Sum[ch[x][1]]+a[x]+c2[ch[x][0]][1]));
     46 }
     47 inline void Update_rev(int x){
     48     if(x==0)return;
     49     swap(c1[x][0],c2[x][0]);
     50     swap(c1[x][1],c2[x][1]);
     51     swap(ch[x][0],ch[x][1]);
     52     r[x]^=1;
     53 }
     54 inline void Update_ops(int x){
     55     if(x==0)return;
     56     a[x]*=-1;Sum[x]*=-1;
     57     swap(c1[x][0],c1[x][1]);
     58     swap(c2[x][0],c2[x][1]);
     59     c1[x][0]*=-1;c1[x][1]*=-1;
     60     c2[x][0]*=-1;c2[x][1]*=-1;
     61     b[x]^=1;
     62 }
     63 inline void Pushdown(int x){
     64     if(r[x]){
     65         Update_rev(ch[x][0]);Update_rev(ch[x][1]);
     66         r[x]=0;
     67     }
     68     if(b[x]){
     69         Update_ops(ch[x][0]);Update_ops(ch[x][1]);
     70         b[x]=0;
     71     }
     72 }
     73 inline void Build(){
     74     ch[Rt=1][1]=2;
     75     for(i=2;i<=n+1;i++){f[i]=i-1;ch[i][1]=i+1;}
     76     f[n+2]=n+1;s[n+2]=1;s[n+1]=2;c1[n+1][0]=c1[n+1][1]=c2[n+1][0]=c2[n+1][1]=a[n];
     77     for(i=n;i>=1;i--)Pushup(i);
     78 }
     79 inline int Get(int x){return ch[f[x]][1]==x;}
     80 inline void Rotate(int x){
     81     bool d=Get(x);int y=f[x];
     82     if(f[y])ch[f[y]][Get(y)]=x;
     83     ch[y][d]=ch[x][d^1];f[ch[y][d]]=y;
     84     f[x]=f[y];f[y]=x;ch[x][d^1]=y;
     85     Pushup(y);
     86 }
     87 inline void P(int x,int y){
     88     if(f[x]!=y)P(f[x],y);
     89     Pushdown(x);
     90 }
     91 inline void Splay(int x,int y){
     92     P(x,y);
     93     for(;f[x]!=y;Rotate(x))
     94     if(f[f[x]]!=y)Rotate(Get(x)==Get(f[x])?f[x]:x);
     95     if(y==0)Rt=x;Pushup(x);
     96 }
     97 inline int Find(int x,int y){
     98     Pushdown(x);
     99     if(s[ch[x][0]]+1==y)return x;
    100     if(s[ch[x][0]]>=y)return Find(ch[x][0],y);
    101     return Find(ch[x][1],y-s[ch[x][0]]-1); 
    102 }
    103 inline int Get_result(int x){
    104     int t=-c1[x][0];
    105     int Res=(t>>1)+t%2;
    106     t=(Res<<1)+Sum[x];
    107     Res+=Abs(t)>>1;
    108     return Res;
    109 }
    110 inline int Query(int x,int y){
    111     int a1=Find(Rt,x-1),a2=Find(Rt,y+1);
    112     Splay(a2,0);Splay(a1,Rt);
    113     return Get_result(ch[a1][1]);
    114 }
    115 inline void Update1(int x,int y){
    116     int a1=Find(Rt,x-1),a2=Find(Rt,y+1);
    117     Splay(a2,0);Splay(a1,Rt);
    118     Update_ops(ch[a1][1]);Pushup(a1);Pushup(a2);
    119 }
    120 inline void Update2(int x,int y){
    121     int a1=Find(Rt,x-1),a2=Find(Rt,y+1);
    122     Splay(a2,0);Splay(a1,Rt);
    123     Update_rev(ch[a1][1]);Pushup(a1);Pushup(a2);
    124 }
    125 int main(){
    126     scanf("%d%d",&n,&m);
    127     scanf("%s",S+1);
    128     for(i=1;i<=n;i++)
    129     if(S[i]=='(')a[i+1]=1;else a[i+1]=-1;
    130     Build();
    131     while(m--){
    132         Read(x);Read(y);Read(z);y++;z++;
    133         if(x==0)Print(Query(y,z));else
    134         if(x==1)Update1(y,z);else if(x==2)Update2(y,z);
    135     }
    136     return 0;
    137 }
    bzoj2209
  • 相关阅读:
    jQuery Mobile动态刷新页面样式
    IE10下阿里旺旺无法快速登录解决办法
    JS复制内容到剪贴板: 兼容IE、Firefox、Chrome、Safari所有浏览器【转】
    python sftp ftp 造轮子,实现多个方法
    synergy ubuntu18.04 windows10
    爬虫之js破解 非常详细
    scrapy的useragent与代理ip
    Xpath的string(.)用法
    selenium cookie 登录
    scrapy爬取迅雷电影天堂最新电影ed2k
  • 原文地址:https://www.cnblogs.com/gjghfd/p/6636749.html
Copyright © 2020-2023  润新知