题意:额那个操作就是让你翻转数列的某个区间
题解:打个翻转标记;不过要及时地在下传前更新,啊啊啊就是不断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\n",shuf[n]);
return 0;
}