Splay模板

题目:https://www.luogu.org/problemnew/show/P3391

主要练习翻转操作;

有好几个地方的顺序写反了,调了好久好久...

整体+1,就可以在翻转时使用左端点-1和右端点+1了;

节点的val是在原数列中的位置,节点所在的树中位置是现在数列的顺序;

所以输出就是中序遍历,输出val。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int const MAXN=1e5+5;
int n,m,cnt,root,del_cur,del_pool[MAXN];
struct N{
    int ch[3],fa,val,rev,size;
}t[MAXN];
int newnode()
{
    if(del_cur)
    {
        int x=del_cur;del_cur--;
        return del_pool[x];
    }
    cnt++;
    return cnt;
}
void del(int x)
{
    del_pool[++del_cur]=x;
    t[x].ch[0]=0;t[x].ch[1]=0;t[x].fa=0;t[x].val=0;
    t[x].rev=0;t[x].size=0;
}
void pushup(int x)
{
    t[x].size=t[t[x].ch[0]].size+t[t[x].ch[1]].size+1;
}
void pushdown(int x)
{
    if(t[x].rev)
    {
        t[t[x].ch[0]].rev^=1;
        t[t[x].ch[1]].rev^=1;
        swap(t[x].ch[0],t[x].ch[1]);//(顺序)
        t[x].rev=0;
    }
}
void rotate(int x)
{
    int y=t[x].fa,z=t[y].fa;
    int d=t[y].ch[1]==x;
    t[z].ch[t[z].ch[1]==y]=x;t[x].fa=z;
    t[y].ch[d]=t[x].ch[d^1];t[t[x].ch[d^1]].fa=y;
    t[x].ch[d^1]=y;t[y].fa=x;//与上行顺序不能反 
    pushup(y);pushup(x);//顺序 
}
void splay(int x,int goal)
{
    while(t[x].fa!=goal)//while而非if 
    {
        int y=t[x].fa,z=t[y].fa;
        if(z!=goal)
        {
            if((t[y].ch[0]==x)==(t[z].ch[0]==y))rotate(y);
            else rotate(x);
        }
        rotate(x);
    }
    pushup(x);
    if(!goal)root=x;
}
void insert(int v)
{
    if(!root)
    {
        root=newnode();
        t[root].val=v;t[root].size=1;
        return;
    }
    int x=root;
    while(1)
    {
        int d=t[x].val<v;
        if(!t[x].ch[d])
        {
            int k=newnode();
            t[x].ch[d]=k;t[k].fa=x;
            t[k].val=v;t[k].size=1;
            splay(k,0);//!
            break;
        }
        x=t[x].ch[d];
    }
}
int Kth(int k)
{
    int u=root;
    while(1)
    {
        pushdown(u);
        if(t[t[u].ch[0]].size+1==k)return u;
        if(t[t[u].ch[0]].size+1>k)u=t[u].ch[0];
        else 
        {
            k-=t[t[u].ch[0]].size+1;
            u=t[u].ch[1];//与上行顺序不能反 
        }
    }
}
void Rev(int L,int R)
{
    int l=Kth(L),r=Kth(R+2);
    splay(l,0);splay(r,l);//r,l而非l,r 
    t[t[r].ch[0]].rev^=1;
}
void print(int x)
{
    pushdown(x);
//    printf("x=%d l=%d r=%d\n",x,t[x].ch[0],t[x].ch[1]);
    if(t[x].ch[0])print(t[x].ch[0]);
    if(t[x].val>1&&t[x].val<=n+1)printf("%d ",t[x].val-1);
    if(t[x].ch[1])print(t[x].ch[1]);
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n+2;i++)insert(i);//+1
    for(int i=1,l,r;i<=m;i++)
    {
        scanf("%d%d",&l,&r);
        Rev(l,r);
    }
    print(root);
    return 0;
}

 

posted @ 2018-05-14 00:36  Zinn  阅读(163)  评论(0编辑  收藏  举报