3223: Tyvj 1729 文艺平衡树
Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 3313 Solved: 1883
[ 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
RunID
User | Problem | Result | Memory | Time | Language | Code_Length | Submit_Time | |
1538282 | ksq2013 | 3223 | Accepted | 5396 kb | 2576 ms | C++/Edit | 2878 B | 2016-07-08 20:57:17 |
#include<cstdio>
#include<iostream>
#define INF 0x3f3f3f3f
#define Key_value ch[ch[root][1]][0]
using namespace std;
bool rev[200100];
int n,m,root,tot,size[200100],key[200100],pre[200100],ch[200100][2];
void NewNode(int &x,int father,int val)
{
x=++tot;
size[x]=1;
key[x]=val;
pre[x]=father;
}
void Update_Rev(int x)
{
rev[x]^=1;
swap(ch[x][0],ch[x][1]);
}
void Push_Up(int x)
{
size[x]=size[ch[x][0]]+size[ch[x][1]]+1;
}
void Push_Down(int x)
{
if(rev[x]){
Update_Rev(ch[x][0]);
Update_Rev(ch[x][1]);
rev[x]=0;
}
}
void build(int &x,int father,int l,int r)
{
if(l>r)return;
int mid=(l+r)>>1;
NewNode(x,father,mid);
build(ch[x][0],x,l,mid-1);
build(ch[x][1],x,mid+1,r);
Push_Up(x);
}
void Init()
{
NewNode(root,0,INF);
NewNode(ch[root][1],root,INF);
build(Key_value,ch[root][1],1,n);
}
int Get_Kth(int x,int k)
{
Push_Down(x);//mistaken codes;
int t=size[ch[x][0]]+1;
if(t==k)return x;
if(t>k)return Get_Kth(ch[x][0],k);
return Get_Kth(ch[x][1],k-t);
}
void Rotate(int x,int kind)
{
int y=pre[x];
Push_Down(y);Push_Down(x);
ch[y][!kind]=ch[x][kind];
pre[ch[x][kind]]=y;
if(pre[y])ch[pre[y]][ch[pre[y]][1]==y]=x;//unfixed;
pre[x]=pre[y];
ch[x][kind]=y;
pre[y]=x;
Push_Up(y);
}
void Splay(int x,int goal)
{
Push_Down(x);
while(pre[x]!=goal){
if(pre[pre[x]]==goal){
Push_Down(pre[x]);
Push_Down(x);
Rotate(x,ch[pre[x]][0]==x);
}
else{
int y=pre[x];
int kind=ch[pre[y]][0]==y;
Push_Down(pre[y]);//mistaken codes&&一遇到向下的操作就Push_Down;
Push_Down(y);//mistaken codes
Push_Down(x);//mistaken codes
if(ch[y][kind]==x){
Rotate(x,!kind);
Rotate(x,kind);
}
else{
Rotate(y,kind);
Rotate(x,kind);
}
}
}
Push_Up(x);
if(goal==0)root=x;
}
void Rev(int l,int r)
{
Splay(Get_Kth(root,l),0);
Splay(Get_Kth(root,r+2),root);
Update_Rev(Key_value);
Push_Up(ch[root][1]);
Push_Up(root);
}
void dfs(int x)
{
if(!x)return;
Push_Down(x);
dfs(ch[x][0]);
if(1<=key[x]&&key[x]<=n)printf("%d ",key[x]);
dfs(ch[x][1]);
}
int main()
{
scanf("%d%d",&n,&m);
Init();
for(int x,y;m;m--){
scanf("%d%d",&x,&y);
Rev(x,y);
}dfs(root);
return 0;
}