zoukankan      html  css  js  c++  java
  • Tyvj 1729 文艺平衡树

    题目背景

    这是一道经典的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,m100000

    闲的没事又打了一遍以前打过的SPLAY的模板。。。。

    然后发现只要遍历BST的时候就要下传标记!!!

    第一次只有find的时候忘了下传标记直接怒T爆零。。。。

    所以:到哪都别忘了下传标记!!!!

    #include<bits/stdc++.h>
    #define ll long long
    #define maxn 100005
    using namespace std;
    int f[maxn],ch[maxn][2];
    int siz[maxn],root,le,ri;
    int n,m,der[maxn],lef,rig;
    
    int build(int l,int r,int fa){
        if(l>r) return 0;
        int mid=l+r>>1;
        f[mid]=fa;
        ch[mid][0]=build(l,mid-1,mid);
        ch[mid][1]=build(mid+1,r,mid);
        siz[mid]=1+siz[ch[mid][0]]+siz[ch[mid][1]];
        return mid;
    }
    
    inline int get(int x){
        return ch[f[x]][1]==x;
    }
    
    inline void update(int x){
        siz[x]=siz[ch[x][0]]+siz[ch[x][1]]+1;
    }
    
    inline void pushdown(int x){
        if(x&&der[x]){
            swap(ch[x][0],ch[x][1]);
            der[ch[x][0]]^=1,der[ch[x][1]]^=1;
            der[x]=0;
        }
    }
    
    inline void rotate(int x){
        pushdown(f[x]),pushdown(x);
        int fa=f[x],ffa=f[fa],tp=get(x);
        ch[fa][tp]=ch[x][tp^1],f[ch[fa][tp]]=fa;
        ch[x][tp^1]=fa,f[fa]=x;
        f[x]=ffa;
        if(ffa) ch[ffa][ch[ffa][1]==fa]=x;
        if(root==fa) root=x;
        update(fa),update(x);
    }
    
    inline void splay(int x,int d){
        for(int fa;(fa=f[x])!=d;rotate(x)) if(f[fa]!=d) rotate((get(fa)==get(x)?fa:x));
    }
    
    inline int find(int k){
        int now=root;
        while(1){
            pushdown(now);
            if(k<=siz[ch[now][0]]){
                now=ch[now][0];
                continue;
            }
            k-=siz[ch[now][0]]+1;
            if(k<=0) return now;
            now=ch[now][1];
        }
    }
    
    void print(int x){
        pushdown(x);
        if(ch[x][0]) print(ch[x][0]);
        if(x!=1&&x!=n+2) printf("%d ",x-1);
        if(ch[x][1]) print(ch[x][1]);
    }
    
    int main(){
        scanf("%d%d",&n,&m);
        root=build(1,n+2,0);
        while(m--){
            scanf("%d%d",&le,&ri);
            lef=find(le),splay(lef,0);
            rig=find(ri+2),splay(rig,root);
            der[ch[ch[root][1]][0]]^=1;
        }
        
        print(root);
        return 0;
    }
  • 相关阅读:
    个人冲刺二(2)
    个人冲刺二(1)
    三个和尚观后感
    每日总结
    个人冲刺(10)
    个人冲刺(9)
    个人冲刺(8)
    个人冲刺(7)
    个人冲刺(6)
    下次视频面试前把电脑摄像头擦干净吧
  • 原文地址:https://www.cnblogs.com/JYYHH/p/8280343.html
Copyright © 2011-2022 走看看