【总结】Splay和各种题目
Splay是平衡树的变种之一,希望大家不要掌握按照Anson的说法,能不写平衡树就不写
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<iostream>
using namespace std;
int n,m;
class BST{
private:
struct node{
int ch[2];
int val,ff,size,cnt,mark;
}t[500010];
int root,tot;
void pushup(int o){
t[o].size=t[t[o].ch[0]].size+t[t[o].ch[1]].size+t[o].cnt;
}
void pushdown(int o){
if(t[o].mark){
t[t[o].ch[0]].mark^=1;
t[t[o].ch[1]].mark^=1;
t[o].mark=0;
swap(t[o].ch[0],t[o].ch[1]);
}
}
void rotate(int x){
int y=t[x].ff,z=t[y].ff;
int k=(t[y].ch[1]==x);
t[z].ch[t[z].ch[1]==y]=x;
t[x].ff=z;t[y].ch[k]=t[x].ch[k^1];
t[t[x].ch[k^1]].ff=y;
t[x].ch[k^1]=y;t[y].ff=x;
pushup(x);pushup(y);
}
public:
void Splay(int x,int goal){
while(t[x].ff!=goal){
int y=t[x].ff,z=t[y].ff;
if(z!=goal)
(t[y].ch[0]==x)^(t[z].ch[0]==y)?rotate(x):rotate(y);
rotate(x);
}
if(!goal)root=x;
}
void Insert(int x){
int u=root,ff=0;
while(u && t[u].val!=x){
ff=u;
u=t[u].ch[x>t[u].val];
}
if(u)t[u].cnt++;
else{
u=++tot;
if(ff)t[ff].ch[x>t[ff].val]=u;
t[u].ch[0]=t[u].ch[1]=0;
t[u].ff=ff;t[u].size=t[u].cnt=1;
t[u].val=x;
}
Splay(u,0);
}
int kth(int x){
int u=root;
while(9247){
pushdown(u);
int y=t[u].ch[0];
if(x>t[y].size+t[u].cnt){
x-=t[y].size+t[u].cnt;
u=t[u].ch[1];
}
else
if(t[y].size>=x)u=y;
else return t[u].val;
}
}
void Work(int l,int r){
l=kth(l);
r=kth(r+2);
Splay(l,0);Splay(r,l);
t[t[t[root].ch[1]].ch[0]].mark^=1;
}
void write(int u){
pushdown(u);
if(t[u].ch[0])write(t[u].ch[0]);
if(t[u].val>1 && t[u].val<n+2)printf("%d ",t[u].val-1);
if(t[u].ch[1])write(t[u].ch[1]);
}
void print(){
write(root);
}
}Splay;
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n+2;i++)Splay.Insert(i);
while(m--){
int l,r;scanf("%d%d",&l,&r);
Splay.Work(l,r);
}
Splay.print();
puts("");
return 0;
}
以下是文艺平衡树
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
#include<iostream>
using namespace std;
int n,m;
class BST{
private:
struct node{
int ch[2];
int val,ff,size,cnt,mark;
}t[500010];
int root,tot;
void pushup(int o){
t[o].size=t[t[o].ch[0]].size+t[t[o].ch[1]].size+t[o].cnt;
}
void pushdown(int o){
if(t[o].mark){
t[t[o].ch[0]].mark^=1;
t[t[o].ch[1]].mark^=1;
t[o].mark=0;
swap(t[o].ch[0],t[o].ch[1]);
}
}
void rotate(int x){
int y=t[x].ff,z=t[y].ff;
int k=(t[y].ch[1]==x);
t[z].ch[t[z].ch[1]==y]=x;
t[x].ff=z;t[y].ch[k]=t[x].ch[k^1];
t[t[x].ch[k^1]].ff=y;
t[x].ch[k^1]=y;t[y].ff=x;
pushup(x);pushup(y);
}
public:
void Splay(int x,int goal){
while(t[x].ff!=goal){
int y=t[x].ff,z=t[y].ff;
if(z!=goal)
(t[y].ch[0]==x)^(t[z].ch[0]==y)?rotate(x):rotate(y);
rotate(x);
}
if(!goal)root=x;
}
void Insert(int x){
int u=root,ff=0;
while(u && t[u].val!=x){
ff=u;
u=t[u].ch[x>t[u].val];
}
if(u)t[u].cnt++;
else{
u=++tot;
if(ff)t[ff].ch[x>t[ff].val]=u;
t[u].ch[0]=t[u].ch[1]=0;
t[u].ff=ff;t[u].size=t[u].cnt=1;
t[u].val=x;
}
Splay(u,0);
}
int kth(int x){
int u=root;
while(9247){
pushdown(u);
int y=t[u].ch[0];
if(x>t[y].size+t[u].cnt){
x-=t[y].size+t[u].cnt;
u=t[u].ch[1];
}
else
if(t[y].size>=x)u=y;
else return t[u].val;
}
}
void Work(int l,int r){
l=kth(l);
r=kth(r+2);
Splay(l,0);Splay(r,l);
t[t[t[root].ch[1]].ch[0]].mark^=1;
}
void write(int u){
pushdown(u);
if(t[u].ch[0])write(t[u].ch[0]);
if(t[u].val>1 && t[u].val<n+2)printf("%d ",t[u].val-1);
if(t[u].ch[1])write(t[u].ch[1]);
}
void print(){
write(root);
}
}Splay;
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n+2;i++)Splay.Insert(i);
while(m--){
int l,r;scanf("%d%d",&l,&r);
Splay.Work(l,r);
}
Splay.print();
puts("");
return 0;
}