题意:额那个操作就是让你翻转数列的某个区间
题解:打个翻转标记;不过要及时地在下传前更新,啊啊啊就是不断updata啊
p.s.还没做二逼二叉树的我
#include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #include<algorithm> using namespace std; #define maxn 101000 //updata很重要 要时常更新才行 struct node { int d,c,f,gg,son[2];//gg就是那个标记= =没错我故意改的 }tr[maxn*2];int len,root; void updata(int x) { if (x==0) return; int lc=tr[x].son[0],rc=tr[x].son[1]; tr[x].c=tr[lc].c+tr[rc].c+1; if (tr[x].gg==1) { tr[lc].gg=1-tr[lc].gg;tr[rc].gg=1-tr[rc].gg; tr[x].son[0]=rc;tr[x].son[1]=lc; tr[x].gg=0; } } void add(int d,int f) { len++;tr[len].gg=0; tr[len].son[0]=tr[len].son[1]=0; tr[len].c=1;tr[len].d=d;tr[len].f=f; if (d<tr[f].d) tr[f].son[0]=len;else tr[f].son[1]=len; } void rotate(int x) { int y=tr[x].f,z=tr[y].f,w,r,R; if (tr[y].son[0]==x) w=1;else w=0; r=tr[x].son[w];R=y; tr[R].son[1-w]=r; if (r!=0) tr[r].f=R; r=x;R=z; tr[R].son[ (y==tr[z].son[0])?0:1]=r; tr[r].f=R; r=y;R=x; tr[R].son[w]=r; tr[r].f=R; updata(y);updata(x); } void splay(int x,int rt) { while (tr[x].f!=rt) { int y=tr[x].f,z=tr[y].f; updata(z);updata(y);updata(x); if (z==rt) rotate(x); else { if ((y==tr[z].son[0])==(x==tr[y].son[0])) rotate(y); else rotate(x);rotate(x); } }if (rt==0) root=x; } int findip(int d) { int x=root; while (tr[x].d!=d) { if (tr[x].d>d) { if (tr[x].son[0]!=0) x=tr[x].son[0]; else break; }else { if (tr[x].son[1]!=0) x=tr[x].son[1]; else break; } }return x; } int findpm(int k) { int x=root; while(1) { updata(x); int lc=tr[x].son[0],rc=tr[x].son[1]; if( k<=tr[lc].c ) x=lc; else if( k>tr[lc].c+1) { k-=tr[lc].c+1;x=rc;} else break; } splay(x,0); return tr[x].d; } void ins(int d) { if (root==0) {add(d,0);root=len;return;} int x=findip(d); add(d,x); updata(x); splay(x,0); } int shuf[maxn],ll=0; void print(int x) { updata(x); if (tr[x].son[0]!=0) print(tr[x].son[0]); shuf[++ll]=tr[x].d; if (tr[x].son[1]!=0) print(tr[x].son[1]); } int main() { //freopen("a.in","r",stdin); //freopen("wyecs.out","w",stdout); int n,m,i,l,r; scanf("%d%d",&n,&m); for (i=1;i<=n;i++) ins(i); for (i=1;i<=m;i++) { scanf("%d%d",&l,&r); if (l!=1 && r!=n) { int p1=findpm(l-1); int p2=findpm(r+1); splay(p1,0); splay(p2,root); tr[tr[p2].son[0]].gg=1-tr[tr[p2].son[0]].gg; }else if (l==1 && r!=n) { int p1=findpm(r+1); splay(p1,0); tr[tr[p1].son[0]].gg=1-tr[tr[p1].son[0]].gg; }else if (l!=1 && r==n) { int p1=findpm(l-1); splay(p1,0); tr[tr[p1].son[1]].gg=1-tr[tr[p1].son[1]].gg; }else tr[root].gg=1-tr[root].gg; }print(root); for (i=1;i<n;i++) printf("%d ",shuf[i]); printf("%d ",shuf[n]); return 0; }