zoukankan      html  css  js  c++  java
  • bzoj3223

    对于区间翻转操作,将l-1(代码中建了[1,n+2]个点,故这里为l)先旋转到根,再将r+1(同上,这里为r+2)旋至其右儿子,则r+1的左儿子即我们要翻转的区间

    tip:在find时已经更新了rev,所以可以splay

    【感觉我的buildtr好恶心啊】

    #include<cstdio>
    #include<cctype>
    #include<algorithm>
    #define maxn 100005
    using namespace std;
    int n,m,rt,tr[maxn][2],fa[maxn],siz[maxn],rev[maxn];
    inline void read(int &x){
        char ch=getchar();x=0;int f=1;
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
        x*=f;
    }
    inline void pushup(int x){siz[x]=siz[tr[x][0]]+siz[tr[x][1]]+1;}
    inline void buildtr(int l,int r,int f,int &cg){
        if(l>r)return;
        int mid=(l+r)>>1;fa[mid]=f;cg=mid;
        if(mid>l)buildtr(l,mid-1,mid,tr[mid][0]);
        if(mid<r)buildtr(mid+1,r,mid,tr[mid][1]);
        pushup(mid);
    }
    inline void pushdown(int x){
        if(rev[x]){
            swap(tr[x][0],tr[x][1]);rev[x]=0;
            rev[tr[x][0]]^=1;rev[tr[x][1]]^=1;
        }
    }
    inline int find(int now,int k){
        pushdown(now);int sz=siz[tr[now][0]];
        if(sz+1==k)return now;
        if(sz>=k)return find(tr[now][0],k);else return find(tr[now][1],k-sz-1);
    }
    inline void rotate(int x,int &root){
        int old=fa[x],oldf=fa[old],whicx=tr[old][1]==x;
        tr[old][whicx]=tr[x][whicx^1];fa[tr[old][whicx]]=old;
        tr[x][whicx^1]=old;fa[old]=x;
        fa[x]=oldf;
        if(old==root)root=x;else {if(oldf)tr[oldf][tr[oldf][1]==old]=x;}
        pushup(old);pushup(x);
    }
    inline void splay(int x,int &root){
        while(x!=root){
            int y=fa[x],z=fa[y];
            if(y!=root)rotate((tr[y][1]==x)==(tr[z][1]==y)?y:x,root);
            rotate(x,root);
        }
    }
    inline void dfs(int now){
        pushdown(now);
        if(tr[now][0])dfs(tr[now][0]);
        if(now!=1 && now!=n+2)printf("%d ",now-1);
        if(tr[now][1])dfs(tr[now][1]);
    }
    void rever(int l,int r)
    {
        int x=find(rt,l),y=find(rt,r+2);
        splay(x,rt);splay(y,tr[x][1]);
        int z=tr[y][0];
        rev[z]^=1;
    }
    int main(){
        read(n);read(m);
        rt=(n+3)>>1;buildtr(1,rt-1,rt,tr[rt][0]);buildtr(rt+1,n+2,rt,tr[rt][1]);pushup(rt);
        while(m--){
            int x,y;read(x);read(y);
            rever(x,y);
        }
        dfs(rt);
    }
  • 相关阅读:
    小技巧
    sql日期函数
    c#发送邮件
    js点滴
    Js序列化时间
    js中string的操作
    原系统中有AD FS , CRM Server ,迁移ADFS 到另一台电脑 , CRM Server用443端口出错
    解决UR 12后ISV目录不能用的问题
    Lucene .Net 版本
    Android 开源项目
  • 原文地址:https://www.cnblogs.com/MikuKnight/p/9079268.html
Copyright © 2011-2022 走看看