【题意】
维护一个有序数列,支持翻转一个区间
【代码】
#include<stdio.h> #include<stdlib.h> struct Node { Node* ch[2]; int v,s,f; int cmp(int x) const { if(x==ch[0]->s+1) return -1; if(x<=ch[0]->s) return 0; return 1; } }; Node *root,*null,*left,*mid,*right,*t,*t2; void init() { null=new Node(); null->ch[0]=null->ch[1]=NULL; null->v=null->s=null->f=0; root=left=mid=right=null; } void build(Node* &o,int l,int r) { int m=(l+r)/2; o=new Node(); o->ch[0]=o->ch[1]=null; o->v=m; o->s=r-l+1; o->f=0; if(l<m) build(o->ch[0],l,m-1); if(r>m) build(o->ch[1],m+1,r); } void pushdown(Node* &o) { if(o->f==0) return; t=o->ch[0]; o->ch[0]=o->ch[1]; o->ch[1]=t; o->f=0; o->ch[0]->f^=1; o->ch[1]->f^=1; } void gets(Node* &o) { o->s = o->ch[0]->s + o->ch[1]->s + 1; } void xz(Node* &o,int d) { Node* k=o->ch[d^1]; pushdown(k); o->ch[d^1]=k->ch[d]; k->ch[d]=o; gets(o); gets(k); o=k; } void splay(Node* &o,int k) { pushdown(o); int d=o->cmp(k),d2,k2; if(d==1) k = k - o->ch[0]->s - 1; if(d!=-1) { Node* p=o->ch[d]; pushdown(p); k2=k; d2=p->cmp(k2); if(d2==1) k2 = k2 - p->ch[0]->s - 1; if(d2!=-1) { splay(p->ch[d2],k2); if(d==d2) xz(o,d^1); else xz(o->ch[d],d2^1); } xz(o,d^1); } } void fl(Node* &o,int k,Node* &left,Node* &t2) { splay(o,k); left=o; t2=o->ch[1]; left->ch[1]=null; gets(left); } Node* hb(Node* left,Node* right) { splay(left,left->s); left->ch[1]=right; gets(left); return left; } void print(Node* o) { pushdown(o); if(o->ch[0]!=null) print(o->ch[0]); if(o->v!=0) printf("%d ",o->v); if(o->ch[1]!=null) print(o->ch[1]); } int main() { int n,m,l,r; scanf("%d%d",&n,&m); init(); build(root,0,n); for(;m>0;m--) { scanf("%d%d",&l,&r); l++; r++; fl(root,l-1,left,t2);//注意:这里的t2不能换为t,因为在splay的pushdown函数中用到了t fl(t2,r-l+1,mid,right); mid->f^=1; root=hb(left,hb(mid,right)); } print(root); return 0; }