BZOJ 3223 文艺平衡树
3223: Tyvj 1729 文艺平衡树
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 5402 Solved: 3196
[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
1 3
1 3
1 4
Sample Output
4 3 2 1 5
HINT
N,M<=100000
Source
正如sourse所说这是一道平衡树的题目,treep对于区间维护好像并不太擅长
我们用splay,splay改变序列是靠中序遍历的不同,区间反转维护lazy标记即可
#include <bits/stdc++.h> #define ll long long #define inf 10000100 using namespace std; inline int read(){ int x=0;int f=1;char ch=getchar(); while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} return x*f; } const int MAXN=1e6+10; namespace zhangenming{ int son[MAXN][2],n,m,siz[MAXN],rev[MAXN]={},fa[MAXN],a[MAXN],tot,key[MAXN],root=0; inline void push_up(int x){ siz[x]=siz[son[x][1]]+siz[son[x][0]]+1; } inline int get(int x){ return x==son[fa[x]][1]; } inline void push_down(int x){ if(!x||!rev[x]) return; rev[son[x][1]]^=1;rev[son[x][0]]^=1; swap(son[x][1],son[x][0]); rev[x]=0; } inline void rote(int x){ push_down(x);push_down(fa[x]); int oldl=fa[x];int wei=get(x);int oldf=fa[fa[x]]; son[oldl][wei]=son[x][wei^1];fa[son[oldl][wei]]=oldl; fa[x]=oldf;fa[oldl]=x;son[x][wei^1]=oldl; if(oldf){ son[oldf][son[oldf][1]==oldl]=x; } push_up(x);push_up(oldl); } inline int build(int leftt,int rightt,int root){ if(leftt>rightt) return 0; int mid=(rightt+leftt)>>1; int now=++tot; rev[now]=0;fa[now]=root;key[now]=a[mid]; int lefttchild=build(leftt,mid-1,now); int righttchild=build(mid+1,rightt,now); son[now][0]=lefttchild;son[now][1]=righttchild;push_up(now); return now; } inline void splay(int xx,int tal){ for(int f;(f=fa[xx])!=tal;rote(xx)){ if(fa[f]!=tal){ rote(get(f)==get(xx)?f:xx); } } if(tal==0) root=xx; } inline int find(int xx){ int now=root; while(1){ push_down(now); if(xx==0) return now; if(xx<=siz[son[now][0]]){ now=son[now][0]; } else{ xx-=siz[son[now][0]]+1; if(xx==0) return now; now=son[now][1]; } } } void print(int root){ push_down(root); if(son[root][0]) print(son[root][0]); if(key[root]!=inf&&key[root]!=-inf) printf("%d ",key[root]); if(son[root][1]) print(son[root][1]); } void init(){ n=read();m=read(); a[1]=inf;a[n+2]=-inf; for(int i=1;i<=n;i++){ a[i+1]=i; } root=build(1,n+2,0); } inline void printt(){ for(int i=1;i<=n+2;i++){ cout<<son[i][0]<<' '<<son[i][1]<<endl; } } void solve(){ while(m--){ int xx=read();int yy=read(); if(xx>=yy) continue; xx=find(xx);yy=find(yy+2); splay(xx,0);splay(yy,xx); rev[son[son[root][1]][0]]^=1; } print(root); } } int main(){ //freopen("All.in","r",stdin); //freopen("a.out","w",stdout); using namespace zhangenming; init(); solve(); return 0; }