欢迎访问~原文出处——博客园-zhouzhendong
去博客园看该题解
题目传送门 - BZOJ3223
题意概括
您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 4 1
数据范围:n<=100000
题解
splay裸题。
加两个哨兵节点。
还有pushdown标记
代码
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstdlib>
using namespace std;
const int N=100005;
int n,m;
struct Splay{
int fa[N],son[N][2],rev[N],val[N],size[N],tot,root;
void clear(){
tot=root=0;
memset(fa,0,sizeof fa);
memset(son,0,sizeof son);
memset(rev,0,sizeof rev);
}
void clear(int x,int v){
val[x]=v;
fa[x]=son[x][0]=son[x][1]=rev[x]=0;
size[x]=1;
}
void pushup(int rt){
int &ls=son[rt][0],&rs=son[rt][1];
size[rt]=size[ls]+size[rs]+1;
}
void pushdown(int rt){
int &ls=son[rt][0],&rs=son[rt][1];
if (!rev[rt])
return;
rev[rt]=0;
rev[ls]^=1;
rev[rs]^=1;
swap(ls,rs);
}
void rec_fa(int rt,int s,int p){
son[rt][p]=s;
fa[s]=rt;
}
int getp(int rt){
return son[fa[rt]][1]==rt;
}
void rotate(int x){
int y=fa[x],z=fa[y],p=getp(x);
rec_fa(z,x,getp(y));
rec_fa(y,son[x][!p],p);
rec_fa(x,y,!p);
pushup(y);
pushup(x);
}
void down(int rt){
if (fa[rt])
down(fa[rt]);
pushdown(rt);
}
void splay(int x,int anst){
down(x);
if (anst==0)
root=x;
for (int y=fa[x];fa[x]!=anst;rotate(x),y=fa[x])
if (fa[y]!=anst)
rotate(getp(x)==getp(y)?y:x);
}
int build(int L,int R){
if (L>R)
return 0;
int rt=++tot,mid=(L+R)>>1;
clear(rt,(1<=mid&&mid<=n)?mid:-1);
int &ls=son[rt][0],&rs=son[rt][1];
ls=build(L,mid-1);
rs=build(mid+1,R);
fa[ls]=fa[rs]=rt;
pushup(rt);
return rt;
}
int find(int x,int k){//find kth
pushdown(x);
int &ls=son[x][0],&rs=son[x][1];
if (size[ls]+1==k)
return x;
if (size[ls]+1>k)
return find(ls,k);
if (size[ls]+1<k)
return find(rs,k-size[ls]-1);
}
void answer(int rt){
pushdown(rt);
int &ls=son[rt][0],&rs=son[rt][1];
if (ls)
answer(ls);
if (val[rt]!=-1)
printf("%d ",val[rt]);
if (rs)
answer(rs);
}
}s;
int main(){
scanf("%d%d",&n,&m);
s.clear();
s.root=s.build(0,n+1);
for (int i=1,L,R;i<=m;i++){
scanf("%d%d",&L,&R);
int x=s.find(s.root,L),y=s.find(s.root,R+2);
s.splay(x,0);
s.splay(y,x);
s.rev[s.son[y][0]]^=1;
}
s.answer(s.root);
return 0;
}
/*
5 3
1 3
1 3
1 4
*/