欢迎访问~原文出处——博客园-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 */