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>
    using namespace std;
    
    const int N=1e5+5;
    
    int n,m;
    struct NODE
    {
        int size,v;
        NODE *fa;
        NODE *son[2];
        bool rev;
        inline int cmp(int val)
        {
            return (v==val)?-1:val>v;
        }
        inline void update()
        {
            this->size=son[0]->size+son[1]->size+1;
        }
    }node[N];
    
    typedef NODE* Tree;
    Tree Root,null,now_node;
    
    inline int read()
    {
        char c=getchar();int num=0,f=1;
        for(;!isdigit(c);c=getchar())
            f=c=='-'?-1:f;
        for(;isdigit(c);c=getchar())
            num=num*10+c-'0';
        return num;
    }
    
    inline void init()
    {
        null=node;
        null->size=null->v=0;
        null->fa=null->son[0]=null->son[1]=null;
        Root=now_node=node;
    }
    
    inline Tree new_node(int x,Tree fa)
    {
        ++now_node;
        now_node->rev=false;
        now_node->size=1;
        now_node->v=x;
        now_node->son[0]=now_node->son[1]=null;
        now_node->fa=fa;
        return now_node;
    }
    
    inline Tree build(int l,int r,Tree fa)
    {
        if(l>r)
            return null;
        int mid=l+r>>1;
        Tree cur=new_node(mid,fa);
        if(l<r)
        {
            cur->son[0]=build(l,mid-1,cur);
            cur->son[1]=build(mid+1,r,cur);
        }
        cur->update();
        return cur;
    }
    
    inline void down(Tree root)
    {
        if(root->rev)
        {
            Tree tmp=root->son[0];
            root->son[0]=root->son[1];
            root->son[1]=tmp;
            if(root->son[0]!=null)
                root->son[0]->rev^=1;
            if(root->son[1]!=null)
                root->son[1]->rev^=1;
            root->rev=0;
        }
    }
    
    inline bool getgx(Tree root)
    {
        return root->fa->son[1]==root;
    }
    
    inline void connect(Tree root,Tree fa,bool flag)
    {
        if(fa!=null)
            fa->son[flag]=root;
        root->fa=fa;
    }
    
    inline void rotate(Tree root)
    {
        Tree fa=root->fa;
        Tree gfa=fa->fa;
        bool a=getgx(root),b=!a;
        connect(root->son[b],fa,a);
        connect(root,gfa,getgx(fa));
        connect(fa,root,b);
        fa->update();
        root->update();
        if(gfa==null)
            Root=root;
    }
    
    inline void splay(Tree root,Tree goal)
    {
        down(root);
        for(;root->fa!=goal;rotate(root))
        {
            if(root->fa->fa!=goal)
                rotate(getgx(root)==getgx(root->fa)?root->fa:root);
        }
    }
    
    inline Tree find(Tree root,int val)
    {
        down(root);
        int left=root->son[0]->size+1;
        if(left==val)
            return root;
        if(left>val)
            return find(root->son[0],val);
        return find(root->son[1],val-left);
    }
    
    inline void reverse(int l,int r)
    {
        Tree a=find(Root,l);
        Tree b=find(Root,r+2);
        splay(a,null);
        splay(b,a);
        Root->update();
        b->son[0]->rev^=1;
    }
    
    inline void dfs(Tree root)
    {
        down(root);
        if(root->son[0]!=null)
            dfs(root->son[0]);
        if(root->v-1<=n&&root->v-1>=1)
            printf("%d ",root->v-1);
        if(root->son[1]!=null)
            dfs(root->son[1]);
    }
    
    int main()
    {
        n=read(),m=read();
        init();
        Root=build(1,n+2,null);
        while(m--)
        {
            int l=read(),r=read();
            reverse(l,r);
        }
        dfs(Root);
        return 0;
    }
  • 相关阅读:
    hadoop balance
    随笔
    ubuntu server 使用parted分区
    程序员内功续
    hadoop——hdfs多硬盘挂载
    hdfs老数据压缩备份的一些问题20120521
    hadoop balance failed
    hoj 2524 Allocate Dormitories 二分图的最大匹配
    HDOJ 分类(转)
    hoj 3008 Matryoshka Dolls Again 最大独立子集
  • 原文地址:https://www.cnblogs.com/lovewhy/p/8717267.html
Copyright © 2011-2022 走看看