zoukankan      html  css  js  c++  java
  • P3391 【模板】文艺平衡树(Splay)

    题目背景

    这是一道经典的Splay模板题——文艺平衡树。

    题目描述

    您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1

    输入输出格式

    输入格式:

    第一行为n,m n表示初始序列有n个数,这个序列依次是(1,2, cdots n-1,n)(1,2,n1,n) m表示翻转操作次数

    接下来m行每行两个数 [l,r][l,r] 数据保证 1 leq l leq r leq n1lrn

    输出格式:

    输出一行n个数字,表示原始序列经过m次变换后的结果

    输入输出样例

    输入样例#1:
    5 3
    1 3
    1 3
    1 4
    输出样例#1:
    4 3 2 1 5

    说明

    n, m leq 100000n,m100000

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define MAXN 100010
    using namespace std;
    int n,m,tot;
    int root,siz[MAXN],fa[MAXN],flag[MAXN],key[MAXN],ch[MAXN][2],cnt[MAXN],ans[MAXN];
    void updeat(int rt){
        int l=ch[rt][0],r=ch[rt][1];
        siz[rt]=siz[l]+siz[r]+1;
    }
    void pushdown(int now){
        if(flag[now]){
            flag[ch[now][0]]^=1;
            flag[ch[now][1]]^=1;
            swap(ch[now][0],ch[now][1]);
            flag[now]=0;
        }
    }
    int getson(int x){
        return ch[fa[x]][1]==x;
    }
    
    void rotate(int x){
        int y=fa[x],z=fa[y],b=getson(x),c=getson(y),a=ch[x][!b];
        if(z) ch[z][c]=x; else root=x; fa[x]=z;
        if(a) fa[a]=y; ch[y][b]=a;
        ch[x][!b]=y;fa[y]=x;
        updeat(y);updeat(x);
    }
    
    void splay(int x,int i){
        while(fa[x]!=i){
            int y=fa[x],z=fa[y];
            if(z==i){
                rotate(x);
            }else{
                if(getson(x)==getson(y)){
                   rotate(y); rotate(x);
                }else{
                   rotate(x); rotate(x);
                }
            }
        }
    }
    int findx(int x){
        int now=root;
        while(1){
            pushdown(now);
            if(ch[now][0]&&x<=siz[ch[now][0]])
                now=ch[now][0];
            else{
                int tmp=(ch[now][0]?siz[ch[now][0]]:0)+1;
                if(x<=tmp)    return now;
                x-=tmp;
                now=ch[now][1];
            }
        }
    }
    int build(int l,int r,int f){
        int now=(l+r)/2;
        fa[now]=f;
        key[now]=ans[now];
        if(l<now)    ch[now][0]=build(l,now-1,now);
        if(r>now)    ch[now][1]=build(now+1,r,now);
        updeat(now);
        return now;
    }
    void print(int now){
        pushdown(now);
        if(ch[now][0])    print(ch[now][0]);
        ans[++tot]=key[now];
        if(ch[now][1])    print(ch[now][1]);    
    }
    int main(){
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n+2;i++)
            ans[i]=i-1;
        root=build(1,n+2,0);
        for(int i=1;i<=m;i++){
            int x,y;
            scanf("%d%d",&x,&y);
            y=y+2;
            int xx=findx(x),yy=findx(y);
            splay(xx,0);splay(yy,xx);
            flag[ch[ch[root][1]][0]]^=1;
        }
        print(root);
        for(int i=1;i<=n;i++)
            printf("%d ",ans[i+1]);
    }
  • 相关阅读:
    nginx安装配置: configure命令
    nginx最简安装
    进程上下文切换
    九卷读书:《操作系统设计与实现》读书笔记
    计算机存储器的层次结构
    线程,进程和并发
    理解Flight框架核心
    Ubuntu16.04安装QQ机器人
    微信支付解决方案
    springboot +nginx +freemarker 模板的简单集成
  • 原文地址:https://www.cnblogs.com/zzyh/p/7351370.html
Copyright © 2011-2022 走看看