• 文艺二叉树


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


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


  • 相关阅读:
    杭电1827
    hdu 3118
    poj 2060
    hdu 2236
    poj 2226
    poj 1719
    poj 1466
    poj 3160
    骑士飞行棋笔记
    基础测试学习笔记
  • 原文地址:https://www.cnblogs.com/Euryale-Rose/p/6527878.html
Copyright © 2020-2023  润新知