• BZOJ 3223: Tyvj 1729 文艺平衡树


    3223: Tyvj 1729 文艺平衡树

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 3629  Solved: 2053
    [Submit][Status][Discuss]

    Description

     

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

    Input

    第一行为n,m n表示初始序列有n个数,这个序列依次是(1,2……n-1,n)  m表示翻转操作次数
    接下来m行每行两个数[l,r] 数据保证 1<=l<=r<=n 

     

    Output

     

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

     

    Sample Input

    5 3

    1 3

    1 3

    1 4

    Sample Output

    4 3 2 1 5

    HINT



    N,M<=100000

    Source

    平衡树

    分析:

    第一次写Splay维护区间翻转操作...

    我们可以用线段树的lazy标记的思想,如果要翻转某个区间,就在子节点打上标记,然后每次访问到带标记的节点的时候就下放标记...

    对于每一个节点,它的权值就是初始序列的序号,每一次翻转区间[l,r]的时候,我们先把排名为l-1的节点转到根节点,这样就保证了[l,+∞)都在根节点的右子树中,然后我们再找到排名为r-1节点,把它转到根节点的右儿子的位置,这样就保证了[l,r]都在r-1节点的左儿子,这样我们直接打标记就好...

    代码:

      1 #include<algorithm>
      2 #include<iostream>
      3 #include<cstring>
      4 #include<cstdio>
      5 //by NeighThorn
      6 using namespace std;
      7 
      8 const int maxn=100000+5;
      9 
     10 int n,m;
     11 int tot,root,w[maxn],ls[maxn],rs[maxn],fa[maxn],siz[maxn],lazy[maxn];
     12 
     13 inline void zig(int x){
     14     int y=fa[x],tmp=siz[y];
     15     if(rs[x])
     16         ls[y]=rs[x],fa[rs[x]]=y,siz[y]=siz[y]-siz[x]+siz[rs[x]],siz[x]=tmp;
     17     else
     18         ls[y]=0,siz[y]=siz[y]-siz[x],siz[x]=tmp;
     19     fa[x]=fa[y];
     20     if(fa[x]){
     21         if(ls[fa[x]]==y)
     22             ls[fa[x]]=x;
     23         else
     24             rs[fa[x]]=x;
     25     }
     26     fa[y]=x,rs[x]=y;
     27 }
     28 
     29 inline void zag(int x){
     30     int y=fa[x],tmp=siz[y];
     31     if(ls[x])
     32         rs[y]=ls[x],fa[ls[x]]=y,siz[y]=siz[y]-siz[x]+siz[ls[x]],siz[x]=tmp;
     33     else
     34         rs[y]=0,siz[y]=siz[y]-siz[x],siz[x]=tmp;
     35     fa[x]=fa[y];
     36     if(fa[x]){
     37         if(ls[fa[x]]==y)
     38             ls[fa[x]]=x;
     39         else
     40             rs[fa[x]]=x;
     41     }
     42     fa[y]=x,ls[x]=y;
     43 }
     44 
     45 inline void splay(int x,int z){
     46     while(fa[x]!=z){
     47         int y=fa[x];
     48         if(fa[y]==z){
     49             if(ls[y]==x)
     50                 zig(x);
     51             else
     52                 zag(x);
     53         }
     54         else{
     55             if(ls[fa[y]]==y){
     56                 if(ls[y]==x)
     57                     zig(y),zig(x);
     58                 else
     59                     zag(x),zig(x);
     60             }
     61             else{
     62                 if(rs[y]==x)
     63                     zag(y),zag(x);
     64                 else
     65                     zig(x),zag(x);
     66             }
     67         }
     68     }
     69     if(!z)
     70         root=x;
     71 }
     72 
     73 inline void ins(int rt,int x){
     74     if(rt==0)
     75         w[++tot]=x,siz[tot]=1,root=tot;
     76     else if(x<w[rt]){
     77         if(ls[rt]==0)
     78             w[++tot]=x,siz[tot]=1,fa[tot]=rt,siz[rt]++,ls[rt]=tot,splay(tot,0);
     79         else
     80             siz[rt]++,ins(ls[rt],x);
     81     }
     82     else{
     83         if(rs[rt]==0)
     84             w[++tot]=x,siz[tot]=1,siz[rt]++,fa[tot]=rt,rs[rt]=tot,splay(tot,0);
     85         else
     86             siz[rt]++,ins(rs[rt],x);
     87     }
     88 }
     89 
     90 inline void push_down(int x){
     91     lazy[x]=0;lazy[ls[x]]^=1,lazy[rs[x]]^=1;
     92     swap(ls[x],rs[x]);
     93 }
     94 
     95 inline int find(int rt,int x){
     96     if(lazy[rt])
     97         push_down(rt);
     98     if(siz[ls[rt]]+1==x){
     99         splay(rt,0);return rt;
    100     }
    101     else if(siz[ls[rt]]>=x)
    102         return find(ls[rt],x);
    103     else
    104         return find(rs[rt],x-siz[ls[rt]]-1);
    105 }
    106 
    107 inline void dfs(int rt){
    108     if(lazy[rt])
    109         push_down(rt);
    110     if(!rt)
    111         return;
    112     if(!ls[rt])
    113         printf("%d ",w[rt]),dfs(rs[rt]);
    114     else
    115         dfs(ls[rt]),printf("%d ",w[rt]),dfs(rs[rt]);
    116 }
    117 
    118 signed main(void){
    119     memset(ls,0,sizeof(ls));
    120     memset(rs,0,sizeof(rs));
    121     memset(fa,0,sizeof(fa));
    122     memset(siz,0,sizeof(siz));
    123     memset(lazy,0,sizeof(lazy));
    124     scanf("%d%d",&n,&m);root=tot=0;
    125     for(int i=1;i<=n;i++)
    126         ins(root,i);
    127     for(int i=1,l,r;i<=m;i++){
    128         scanf("%d%d",&l,&r);
    129         if(l==1&&r==tot)
    130             lazy[root]^=1;
    131         else if(l==1)
    132             r=find(root,r+1),splay(r,0),lazy[ls[r]]^=1;
    133         else if(r==tot)
    134             l=find(root,l-1),splay(l,0),lazy[rs[l]]^=1;
    135         else
    136             l=find(root,l-1),r=find(root,r+1),splay(l,0),splay(r,l),lazy[ls[r]]^=1;
    137     }
    138     dfs(root);puts("");
    139     return 0;
    140 }
    View Code

    by NeighThorn

  • 相关阅读:
    一次完整的HTTP事务的过程
    移动端事件
    canvas 在视频中的用法
    理解Vue
    改变console.log的输出样式
    百度下拉搜索案例
    Vue总结
    字符串、正则
    .Net Mvc框架知识点
    Lowest Common Ancestor of a Binary Tree -- LeetCode
  • 原文地址:https://www.cnblogs.com/neighthorn/p/6150346.html
Copyright © 2020-2023  润新知