bzoj3223
3223: Tyvj 1729 文艺平衡树
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 3700 Solved: 2097
[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
抄了抄模板,自己yy不出来
区间操作
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; #define N 100010 int n,m,root; int size[N],fa[N],tag[N]; int child[N][2]; void update(int x) { size[x]=size[child[x][0]]+size[child[x][1]]+1; } void zig(int x) { int y=fa[x]; fa[x]=fa[y]; child[fa[x]][y==child[fa[x]][1]]=x; fa[child[x][1]]=y; child[y][0]=child[x][1]; fa[y]=x; child[x][1]=y; update(x); update(y); } void zag(int x) { int y=fa[x]; // printf("----------------\n"); // printf("fa[x]=%d\n",fa[x]); fa[x]=fa[y]; child[fa[x]][y==child[fa[x]][1]]=x; // printf("x=%d\n",x); // printf("fa[x]=%d\n",fa[x]); // printf("----------------\n"); fa[child[x][0]]=y; child[y][1]=child[x][0]; fa[y]=x; child[x][0]=y; update(x); update(y); } void splay(int x,int t) { int a=fa[t]; while(fa[x]!=a) { int y=fa[x],z=fa[y]; if(y==t) { child[t][0]==x?zig(x):zag(x); break; } x==child[y][0]?zig(x):zag(x); x==child[z][0]?zig(x):zag(x); update(x); } if(!fa[x]) root=x; update(root); } void pushdown(int x) { if(tag[x]) { swap(child[x][0],child[x][1]); tag[child[x][0]]^=1; tag[child[x][1]]^=1; tag[x]^=1; } } int find(int x,int rank) { pushdown(x); // printf("x=%d rank=%d\n",x,rank); if(size[child[x][0]]+1==rank) return x; else if(size[child[x][0]]>=rank) return find(child[x][0],rank); else return find(child[x][1],rank-size[child[x][0]]-1); } void turn(int a,int b) { int x=find(root,a-1),y=find(root,b+1); splay(x,root); splay(y,child[root][1]); tag[child[child[root][1]][0]]^=1; } int main() { scanf("%d%d",&n,&m); root=1; update(1); for(int i=2;i<=n+2;i++) { fa[i]=i-1; child[i-1][1]=i; update(i); } while(m--) { int a,b; scanf("%d%d",&a,&b); a++; b++; turn(a,b); } // printf("YES\n"); // printf("root=%d\n",root); for(int i=2;i<=n+1;i++) { // printf("\n----------------\n"); printf("%d ",find(root,i)-1); } return 0; }