3223. 文艺平衡树【平衡树-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
1 3
1 4
1 3
1 3
1 4
Sample Output
4 3 2 1 5
HINT
N,M<=100000
板子啊,常规操作
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #define MAXN (100000+10) 5 using namespace std; 6 int Father[MAXN]; 7 int Son[MAXN][2]; 8 int Size[MAXN]; 9 int Smark[MAXN]; 10 int a[MAXN]; 11 int Key[MAXN]; 12 int Root; 13 int n,m,l,r; 14 int Get(int x) 15 { 16 return Son[Father[x]][1]==x; 17 } 18 19 void Update(int x) 20 { 21 Size[x]=Size[Son[x][1]]+Size[Son[x][0]]+1; 22 } 23 24 void Pushdown(int x) 25 { 26 if (x && Smark[x]) 27 { 28 Smark[Son[x][0]]^=1; 29 Smark[Son[x][1]]^=1; 30 swap(Son[x][0],Son[x][1]); 31 Smark[x]=0; 32 } 33 } 34 35 void Rotate(int x) 36 { 37 Pushdown(Father[x]); 38 Pushdown(x); 39 int fa=Father[x]; 40 int fafa=Father[fa]; 41 int wh=Get(x); 42 43 Son[fa][wh]=Son[x][wh^1]; 44 Father[fa]=x; 45 if (Son[fa][wh]) Father[Son[fa][wh]]=fa; 46 47 Father[x]=fafa; 48 Son[x][wh^1]=fa; 49 if (fafa) Son[fafa][Son[fafa][1]==fa]=x; 50 51 Update(fa); 52 Update(x); 53 } 54 55 void Splay(int x,int tar) 56 { 57 for (int fa;(fa=Father[x])!=tar;Rotate(x)) 58 if (Father[fa]!=tar) 59 Rotate(Get(fa)==Get(x)?fa:x); 60 if (!tar) Root=x; 61 } 62 63 void Build (int l,int r,int fa) 64 { 65 if (l>r) return; 66 int mid=(l+r)/2; 67 if (mid<fa) Son[fa][0]=mid; 68 if (mid>fa) Son[fa][1]=mid; 69 Father[mid]=fa; 70 Size[mid]=1; 71 Key[mid]=a[mid]; 72 if (l==r) return; 73 Build(l,mid-1,mid); 74 Build(mid+1,r,mid); 75 Update(mid); 76 } 77 78 int Findx(int x) 79 { 80 int now=Root; 81 while (1) 82 { 83 Pushdown(now); 84 if (x<=Size[Son[now][0]]) 85 now=Son[now][0]; 86 else 87 { 88 x-=Size[Son[now][0]]; 89 if (x==1) return now; 90 x-=1; 91 now=Son[now][1]; 92 } 93 } 94 } 95 96 void Rever(int l,int r) 97 { 98 int f1=Findx(l); 99 int f2=Findx(r+2); 100 Splay(f1,0); 101 Splay(f2,f1); 102 Smark[Son[Son[Root][1]][0]]^=1; 103 } 104 105 void Write(int x) 106 { 107 Pushdown(x); 108 if (Son[x][0]) Write(Son[x][0]); 109 if (x>=2 && x<=n+1) printf("%d ",Key[x]); 110 if (Son[x][1]) Write(Son[x][1]); 111 } 112 113 int main() 114 { 115 scanf("%d%d",&n,&m); 116 for (int i=2;i<=n+1;++i) 117 a[i]=i-1; 118 Build(1,n+2,0);Root=(n+3)/2; 119 for (int i=1;i<=m;++i) 120 { 121 scanf("%d%d",&l,&r); 122 if (l>=r) continue; 123 Rever(l,r); 124 } 125 Write(Root); 126 }