zoukankan      html  css  js  c++  java
  • 洛谷3391 文艺平衡树 平衡树模板95

    上次被火星人prefix吊打,突然发现已经不会写splay了

    于是来道模板题

    区间反转?

    打一些lazy标记,感觉和线段树没有差太多,而且交换左右儿子这操作真是妙

    lazy标记

    下传的时间要注意有些东西会变

     1 #include <bits/stdc++.h>
     2 #define N 500000
     3 #define mid (l+r>>1)
     4 using namespace std;
     5 int n,m,x,y;
     6 struct spla
     7 {
     8     int fa[N],c[N][2],size[N],tr[N];
     9     bool rev[N];
    10     int NODE,rt;
    11     void up(int x)
    12     {
    13         size[x]=size[c[x][0]]+size[c[x][1]]+1;
    14     }
    15     void down(int x)
    16     {
    17         if(rev[x]) swap(c[x][0],c[x][1]),rev[x]=0,rev[c[x][0]]^=1,rev[c[x][1]]^=1;
    18     }
    19     void rot(int x)
    20     {
    21         int y=fa[x];
    22         down(y);down(x);
    23         bool k=c[y][1]==x;
    24         if(fa[y]) c[fa[y]][c[fa[y]][1]==y]=x;    else rt=x;
    25         fa[x]=fa[y];fa[y]=x;c[y][k]=c[x][!k];fa[c[x][!k]]=y;c[x][!k]=y;
    26         up(y);up(x);
    27     }
    28     void splay(int x,int y)
    29     {
    30         for(int t;(t=fa[x])!=y;rot(x))
    31         if(fa[t]!=y)
    32             rot(c[t][1]==x^c[fa[t]][1]==t?x:t);
    33     } 
    34     int build(int l,int r)
    35     {
    36         int now=++NODE;tr[now]=mid;size[now]=r-l+1;rev[now]=0;
    37         if(l<mid)
    38         {
    39             int ls=build(l,mid-1);
    40             fa[ls]=now;
    41             c[now][0]=ls;
    42         }
    43         if(mid<r)
    44         {
    45             int rs=build(mid+1,r);
    46             fa[rs]=now;
    47             c[now][1]=rs;
    48         }
    49         return now;
    50     }
    51     int pos(int x)
    52     {
    53         int now,k;
    54         for(now=rt;down(now),size[c[now][0]]+1!=x;k=x>size[c[now][0]],x-=k*(size[c[now][0]]+1),now=c[now][k]);
    55         return now;
    56     }
    57     void reverse(int x,int y)
    58     {
    59         splay(pos(x),0);
    60         splay(pos(y+2),rt);
    61         rev[c[c[rt][1]][0]]^=1;
    62     }
    63     void dfs(int now)
    64     {
    65         down(now);
    66         if(c[now][0]) dfs(c[now][0]);
    67         if(tr[now]>0 && tr[now]<=n)
    68         printf("%d ",tr[now]);
    69         if(c[now][1]) dfs(c[now][1]);
    70     }
    71 } sp;
    72 int main()
    73 {
    74     scanf("%d%d",&n,&m);
    75     sp.rt=sp.build(0,n+1);
    76     for(int i=1;i<=m;i++)
    77         scanf("%d%d",&x,&y),sp.reverse(x,y);
    78     sp.dfs(sp.rt);
    79     return 0;
    80 }
  • 相关阅读:
    Java面试题2(转)
    Java面试题1(转)
    RabbitMq、ActiveMq、ZeroMq、kafka之间的比较,资料汇总
    Java List与数组之间的转换
    JAVA面试题(3)
    JAVA面试题(2)
    JAVA面试题(1)
    SpringMVC 后台怎么获取前台jsp页面中file中的文件
    QMessageBox中按钮的汉化
    关于字符串的一些重要方法
  • 原文地址:https://www.cnblogs.com/wanglichao/p/7278382.html
Copyright © 2011-2022 走看看