[bzoj3223]文艺平衡树[splay]

  //BY HZWER  1 #include<iostream>
  2 #include<cstdio>
  3
  4 using namespace std;
  5
  6 inline int read()
  7 {
  8     int x=0,f=1;char ch=getchar();
  9     while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
 10     while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
 11     return x*f;
 12 }
 13
 14 int n,m,sz,rt;
 15 int fa[100005],c[100005][2],id[100005];
 16 int size[100005];
 17 bool rev[100005];
 18
 19 void pushup(int k)
 20 {
 21     int l=c[k][0],r=c[k][1];
 22     size[k]=size[l]+size[r]+1;
 23 }
 24
 25 void pushdown(int k)
 26 {
 27     int l=c[k][0],r=c[k][1];
 28
 29     if(rev[k])
 30     {
 31         swap(c[k][0],c[k][1]);
 32         rev[l]^=1;rev[r]^=1;
 33         rev[k]=0;
 34     }
 35 }
 36
 37 void rotate(int x,int &k)
 38 {
 39     int y=fa[x],z=fa[y],l,r;
 40
 41     if(c[y][0]==x)l=0;else l=1;r=l^1;
 42     if(y==k)k=x;
 43     else {if(c[z][0]==y)c[z][0]=x;else c[z][1]=x;}
 44
 45     fa[x]=z;fa[y]=x;fa[c[x][r]]=y;
 46     c[y][l]=c[x][r];c[x][r]=y;
 47     pushup(y);pushup(x);
 48 }
 49
 50 void splay(int x,int &k)
 51 {
 52     while(x!=k)
 53     {
 54         int y=fa[x],z=fa[y];
 55         if(y!=k)
 56         {
 57             if((c[y][0]==x)^(c[z][0]==y))rotate(x,k);
 58             else rotate(y,k);
 59         }
 60
 61         rotate(x,k);
 62     }
 63 }
 64
 65 int find(int k,int rank)
 66 {
 67     pushdown(k);
 68     int l=c[k][0],r=c[k][1];
 69
 70     if(size[l]+1==rank)return k;
 71     else if(size[l]>=rank)return find(l,rank);
 72     else return find(r,rank-size[l]-1);
 73 }
 74
 75 void rever(int l,int r)
 76 {
 77     int x=find(rt,l),y=find(rt,r+2);
 78     splay(x,rt);splay(y,c[x][1]);
 79     int z=c[y][0];
 80     rev[z]^=1;
 81 }
 82
 83 void build(int l,int r,int f)
 84 {
 85     if(l>r)return;
 86     int now=id[l],last=id[f];
 87
 88     if(l==r)
 89     {
 90         fa[now]=last;size[now]=1;
 91         if(l<f)c[last][0]=now;
 92         else c[last][1]=now;
 93         return;
 94     }
 95
 96     int mid=(l+r)>>1;now=id[mid];
 97
 98     build(l,mid-1,mid);build(mid+1,r,mid);
 99     fa[now]=last;pushup(mid);
100
101     if(mid<f)c[last][0]=now;
102     else c[last][1]=now;
103 }
104
105 int main()
106 {
107     n=read();m=read();
108
109     for(int i=1;i<=n+2;i++)
110         id[i]=++sz;
111
112     build(1,n+2,0);rt=(n+3)>>1;
113
114     for(int i=1;i<=m;i++)
115     {
116         int l=read(),r=read();
117         rever(l,r);
118     }
119
120     for(int i=2;i<=n+1;i++)
121         printf("%d ",find(rt,i)-1);
122
123     return 0;
124 }
时间: 2024-10-31 13:05:12

[bzoj3223]文艺平衡树[splay]的相关文章

JZYZOJ1998 [bzoj3223] 文艺平衡树 splay 平衡树

http://172.20.6.3/Problem_Show.asp?id=1998 平衡树区间翻转的板子,重新写一遍,给自己码一个板子. 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #include<cstdlib> 7 using namespace std; 8 cons

[bzoj3223]文艺平衡树(splay区间反转模板)

解题关键:splay模板题. #include<cstdio> #include<cstring> #include<algorithm> #include<cstdlib> #include<iostream> #include<cmath> using namespace std; typedef long long ll; const int N = 100005; int ch[N][2],par[N],val[N],cnt[

BZOJ3223: Tyvj 1729 文艺平衡树 [splay]

3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 3595  Solved: 2029[Submit][Status][Discuss] Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1 Input 第一行为n,m n表示初始序列有n个数,这个序列依次

Tyvj P1729 文艺平衡树 Splay

题目: http://tyvj.cn/p/1729 P1729 文艺平衡树 时间: 1000ms / 空间: 131072KiB / Java类名: Main 背景 此为平衡树系列第二道:文艺平衡树 描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1 输入格式 第一行为n,m n表示初始序列有n个数,这个序列依次是(1,2……n-1,n)  m表示翻转操作次数

洛谷 P3391 【模板】文艺平衡树(Splay)

题目背景 这是一道经典的Splay模板题--文艺平衡树. 题目描述 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1 输入格式: 第一行为n,m n表示初始序列有n个数,这个序列依次是 (1,2,?n?1,n) m表示翻转操作次数 接下来m行每行两个数 [l,r][l,r] 数据保证 1≤l≤r≤n 输出格式: 输出一行n个数字,表示原始序列经过m次变换后的结果

[BZOJ3223]文艺平衡树 无旋Treap

3223: Tyvj 1729 文艺平衡树 Time Limit: 10 Sec  Memory Limit: 128 MB 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<

[BZOJ3223] [Tyvj1729] 文艺平衡树 (splay)

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

[Bzoj3223][Tyvj1729] 文艺平衡树(splay/无旋Treap)

题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3223 平衡树处理区间问题的入门题目,普通平衡树那道题在维护平衡树上是以每个数的值作为维护的标准,而处理区间问题时,维护平衡树的应该是每个位置的下标,所以平衡树中序遍历时应该是当前区间的样子.例如: {1 2 3 4 5}翻转区间1 3,则中序遍历应该输出{3,2,1,4,5}. 提供splay和无旋Treap的做法. splay做法: 1 #include<bits/stdc++.h>

bzoj 3223 文艺平衡树 Splay 打标志

是NOI2003Editor的一个子任务 1 #include <cstdio> 2 #include <vector> 3 #define maxn 100010 4 using namespace std; 5 6 struct Splay { 7 int pre[maxn], son[maxn][2], siz[maxn], rev[maxn], root; 8 9 void update( int nd ) { 10 siz[nd] = siz[son[nd][0]]+si