文艺二叉树

题意:额那个操作就是让你翻转数列的某个区间


题解:打个翻转标记;不过要及时地在下传前更新,啊啊啊就是不断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;
}


原文地址:https://www.cnblogs.com/Euryale-Rose/p/6527878.html