zoukankan      html  css  js  c++  java
  • bzoj2329: [HNOI2011]括号修复

    传送门

    觉得自底向上的splay贼神奇我竟然天真地写了自底向上,就不用kth了啊直接找到多好,然后发现我怕是个zz,我一reverse序号早乱了。。。

    所以不能自底向上,至少我认为那是没有意义的。

    然后就是取反的时候也是取异或,每次都会忘了这点。

    //Achen
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<vector>
    #include<cstdio>
    #include<queue>
    #include<cmath>
    const int N=200010;
    typedef long long LL;
    using namespace std;
    int rt,n,m,tot;
    char s[N],o[10];
    
    template<typename T>void read(T &x)  {
        char ch=getchar(); x=0; T f=1;
        while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
        if(ch=='-') f=-1,ch=getchar();
        for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; x*=f;
    }
    
    int p[N],ch[N][2],v[N],flip[N],op[N],cover[N],sum[N],lmi[N],lmx[N],rmx[N],rmi[N],sz[N];
    #define lc ch[x][0]
    #define rc ch[x][1]
    void update(int x) {
        sum[x]=sum[lc]+sum[rc]+v[x];
        sz[x]=sz[lc]+sz[rc]+1;
        lmi[x]=min(lmi[lc],sum[lc]+v[x]+lmi[rc]);
        lmx[x]=max(lmx[lc],sum[lc]+v[x]+lmx[rc]);
        rmi[x]=min(rmi[rc],sum[rc]+v[x]+rmi[lc]);
        rmx[x]=max(rmx[rc],sum[rc]+v[x]+rmx[lc]); 
    }
    
    void cover_it(int x,int w) {
        sum[x]=sz[x]*w; v[x]=w; 
        cover[x]=w; flip[x]=op[x]=0; 
        lmi[x]=rmi[x]=min(0,sz[x]*w); 
        lmx[x]=rmx[x]=max(0,sz[x]*w);
    }
    
    void get_oppo(int x) {
        swap(lmi[x],lmx[x]); 
        swap(rmi[x],rmx[x]);
        if(cover[x]) cover[x]*=-1; else op[x]^=1; //取反也是异或! 
        sum[x]*=-1,v[x]*=-1;
        lmi[x]*=-1,lmx[x]*=-1;
        rmi[x]*=-1,rmx[x]*=-1;
    }
    
    void reverse(int x) {
        swap(lc,rc);
        swap(lmi[x],rmi[x]);
        swap(lmx[x],rmx[x]);
        flip[x]^=1;
    }
    
    void down(int x) {
        if(!cover[x]&&!op[x]&&!flip[x]) return;
        if(cover[x]) {
            if(lc) cover_it(lc,cover[x]);
            if(rc) cover_it(rc,cover[x]); 
        }
        if(op[x]) {
            if(lc) get_oppo(lc);
            if(rc) get_oppo(rc);
        }
        if(flip[x]) {
            if(lc) reverse(lc);
            if(rc) reverse(rc);
        }
        cover[x]=op[x]=flip[x]=0; 
    }
    
    void rotate(int x) {
        int y=p[x],z=p[y],l=(x==ch[y][1]),r=l^1;
        if(z) ch[z][y==ch[z][1]]=x; p[x]=z;
        ch[y][l]=ch[x][r]; p[ch[x][r]]=y;
        ch[x][r]=y; p[y]=x;
        update(y); update(x);
    }
    
    void splay(int x,int FA) {
        /*static int g[N],top=0,tp;
        for(tp=x;tp!=FA;tp=p[tp]) g[++top]=tp;
        g[++top]=tp;
        while(top) down(g[top--]);*/ //不能自底向上! 
        for(;p[x]!=FA;rotate(x)) {
            int y=p[x],z=p[y];
            if(z!=FA) ((x==ch[y][1])^(y==ch[z][1]))?rotate(x):rotate(y); 
        }
        if(!FA) rt=x; 
    }
    
    int build(int sz) {
        if(!sz) return 0;
        int ls,rs,x;
        ls=build(sz>>1);
        x=++tot;
        rs=build(sz-(sz>>1)-1);
        if(ls) p[ls]=x; lc=ls; 
        if(rs) p[rs]=x; rc=rs;
        update(x);
        return x;
    }
    
    int kth(int k) {
        for(int x=rt;x;) {
            down(x);
            if(sz[lc]+1==k) return x;
            if(sz[lc]+1<k) k-=(sz[lc]+1),x=rc;
            else x=lc;
        } return -1;
    }
    
    int get_it(int l,int r) {
        l=kth(l); r=kth(r+2);
        splay(l,0); splay(r,l);
        return ch[r][0];
    }
    
    int main() {
    #ifdef DEBUG
        freopen(".in","r",stdin);
        freopen(".out","w",stdout);
    #endif
        read(n); read(m);
        scanf("%s",s+1);
        for(int i=1;i<=n;i++) v[i+1]=(s[i]=='(')?-1:1;
        /*ch[n+1][1]=n+2; p[n+2]=n+1;
        ch[n+2][0]=build(n); p[ch[n+2][0]]=n+2;
        update(n+2); update(n+1); rt=n+1;*/
        rt=build(n+2);
        while(m--) {
            scanf("%s",o);
            int l,r,w;
            read(l); read(r);
            int x=get_it(l,r);
            if(o[0]=='R') {
                scanf("%s",o);
                w=(o[0]=='(')?-1:1;
                cover_it(x,w); 
            }
            else if(o[0]=='S') reverse(x);
            else if(o[0]=='I') get_oppo(x);
            else if(o[0]=='Q') {
                int ans=(lmx[x]+1)/2+(-rmi[x]+1)/2; //// no lmi rmx
                printf("%d
    ",ans);
            }
            update(p[x]); update(p[p[x]]); 
        }
        return 0;
    }
    /*
    4 4
    ((((
    Replace 1 2 )
    Swap 2 3
    Invert 3 4
    Query 1 4 
    
    4 3
    ((((
    Swap 2 4 
    Swap 3 4 
    Query 1 4 
    */
    View Code

     

    //Serene
    #include<algorithm>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #include<cmath>
    #include<ctime>
    using namespace std;
    #define ll long long
    #define db double
    int n=40,m=50;
    
    char cc; ll ff;
    template<typename T>void read(T& aa) {
        aa=0;cc=getchar();ff=1;
        while((cc<'0'||cc>'9')&&cc!='-') cc=getchar();
        if(cc=='-') ff=-1,cc=getchar();
        while(cc>='0'&&cc<='9') aa=aa*10+cc-'0',cc=getchar();
        aa*=ff;
    }
    
    int main() {
        srand((unsigned)time(NULL));
        printf("%d %d
    ",n,m);
        for(int i=1;i<=n;i++) {
            int o=rand()%2;
            if(o==1) printf("(");
            else printf(")");
        } puts("");
        for(int i=1;i<=m;i++) {
            int o=rand()%4;
            int l=rand()%n+1,r=rand()%n+1;
            if(l>r) swap(l,r);
            if(o==1) {
                printf("Replace "); 
                printf("%d %d ",l,r);
                o=rand()%2;
                if(o==1) printf("(");
                else printf(")");
            }
            else if(o==2) {
                printf("Query "); 
                printf("%d %d ",l,r);
            }
            else if(o==3) {
                printf("Swap "); 
                printf("%d %d ",l,r);
            }
            else {
                printf("Invert "); 
                printf("%d %d ",l,r);
            }
            puts("");
        }
        return 0;
    }
    rand
  • 相关阅读:
    第01组 Alpha冲刺 总结
    第01组 Alpha冲刺 (6/6)
    小黄衫买家秀及获奖感言
    软工实践个人总结
    实验 7:OpenDaylight 实验——Python 中的 REST API 调用
    实验 6:OpenDaylight 实验——OpenDaylight 及 Postman 实现流表下发
    实验 5:OpenFlow 协议分析和 OpenDaylight 安装
    SDN实验 4:Open vSwitch 实验——Mininet 中使用 OVS 命令
    实验 3:Mininet 实验——测量路径的损耗率
    2020软件工程个人编程作业一:统计分析GitHub 的用户行为数据
  • 原文地址:https://www.cnblogs.com/Achenchen/p/8537542.html
Copyright © 2011-2022 走看看