zoukankan      html  css  js  c++  java
  • BZOJ 3223 Tyvj 1729 文艺平衡树 | Splay 维护序列关系

    题解:

    每次reverse(l,r)

    把l-1转到根,r+1变成他的右儿子,给r+1的左儿子打个标记就是一次反转操作了

    每次find和dfs输出的时候下放标记,把左儿子和右儿子换一下

    记得建树的时候建0到n+1

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #define N 100010
    #define which(x) (ls[fa[(x)]]==(x))
    using namespace std;
    int sz[N],ls[N],rs[N],fa[N],n,m,root,flag[N],id[N],idx;
    void upt(int x) {sz[x]=1+sz[ls[x]]+sz[rs[x]];}
    int read()
    {
        int ret=0,neg=1;
        char j=getchar();
        for (;j>'9' || j<'0';j=getchar())
        if (j=='-') neg=-1;
        for (;j>='0' && j<='9';j=getchar())
        ret=ret*10+j-'0';
        return ret*neg;
    }
    void write(int x)
    {
        if (x<0) x=-x;
        if (x>=10) write(x/10);
        putchar(x%10+'0');
    }
    void swap_son(int u)
    {
        if (!u) return;
        flag[u]^=1;
        swap(ls[u],rs[u]);
        upt(u);
    }
    void pushdown(int u)
    {
        if (!flag[u]) return ;
        swap_son(ls[u]),swap_son(rs[u]);
        flag[u]=0;
    }
    int Build(int l, int r)
    {
        int mid=l+r>>1,u=++idx;
        id[u]=mid;
        if(mid>l) ls[u]=Build(l,mid-1),fa[ls[u]]=u;
        if(mid<r) rs[u]=Build(mid+1,r),fa[rs[u]]=u;
        upt(u);
        return u;
    }
    void Rotate(int u)
    {
        int v=fa[u],w=fa[v],b=which(u)?rs[u]:ls[u];
        if(w) which(v)?ls[w]=u:rs[w]=u;
        which(u)?(ls[v]=b,rs[u]=v):(rs[v]=b,ls[u]=v);
        fa[u]=w,fa[v]=u;
        if(b) fa[b]=v;
        upt(v),upt(u);
    }
    void Splay(int u, int tar)
    {
        while(fa[u] != tar)
        {
        if(fa[fa[u]] != tar)
        {
            if(which(u) == which(fa[u])) Rotate(fa[u]);
            else Rotate(u);
        }
        Rotate(u);
        }
        if(!tar) root = u;
    }
    int find(int k)
    {
        int u=root;
        pushdown(u);
        while (sz[ls[u]]+1!=k && u)
        {
        if (sz[ls[u]]>=k) u=ls[u];
        else k-=sz[ls[u]]+1,u=rs[u];
        pushdown(u);
        }
        return u;
    }
    void rev(int l,int r)
    {
        int u=find(l-1),v=find(r+1);
        Splay(u,0);
        Splay(v,u);
        swap_son(ls[rs[root]]);
    }
    void dfs(int u)
    {
        pushdown(u);
        if (ls[u]) dfs(ls[u]);
        if (id[u]>1 && id[u]<n+2) write(id[u]-1),putchar(' ');
        if (rs[u]) dfs(rs[u]);
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        root=Build(1,n+2);
        for (int i=1,l,r;i<=m;i++)
        l=read(),r=read(),rev(l+1,r+1);
        dfs(root);
        return 0;
    }
  • 相关阅读:
    Java读源码之ReentrantLock(2)
    Java读源码之ReentrantLock
    Java8新特性之Stream
    Spring Cloud Contract 微服务契约测试
    Springboot + 持久层框架JOOQ
    Groovy语法糖以及DSL
    Java自定义注解
    Java8新特性之接口defualt,static方法
    Nginx + uWSGI + Python + Django构建必应高清壁纸站
    Kafka,RocketMQ,RabbitMQ部署与使用体验
  • 原文地址:https://www.cnblogs.com/mrsheep/p/8135341.html
Copyright © 2011-2022 走看看