【codevs2333】【BZOJ2002】弹飞绵羊,第一次的LCT

传送门1
传送门2
写在前面:开始种树
思路:分块 or LCT,主要结合了黄学长的模版,同时感谢char哥、Yveh、Shallwe的帮助,做法什么的建议大家还是去网上找,有很多神犇讲解得不错,蒟蒻对这种模版也说不来什么,就这样吧……
注意:找一个数组记录各个装置弹出后到的位置,以便link,cut操作
代码:

#include<bits/stdc++.h>
using namespace std;
int n,m,opt,x,y;
int stacks[200010],next[200010];
struct tree
{
    int fa,ch[2],data,siz,lazy;
}a[200010];
int in()
{
    int t=0;
    char ch=getchar();
    while (ch>'9'||ch<'0') ch=getchar();
    while (ch>='0'&&ch<='9') t=t*10+ch-'0',ch=getchar();
    return t;
}
bool isroot(int x)
{
    return a[a[x].fa].ch[0]!=x&&a[a[x].fa].ch[1]!=x;
}
void ct(int x)
{
    a[x].siz=a[a[x].ch[0]].siz+a[a[x].ch[1]].siz+1;
}
void pushdown(int x)
{
    if (!a[x].lazy) return;
    a[a[x].ch[0]].lazy^=1;
    a[a[x].ch[1]].lazy^=1;
    swap(a[x].ch[0],a[x].ch[1]);
    a[x].lazy=0;
}
void rorate(int x,bool mk)
{
    int y=a[x].fa;
    if (!isroot(y))
    {
        if (a[a[y].fa].ch[0]==y) a[a[y].fa].ch[0]=x;
        else a[a[y].fa].ch[1]=x;
    }
    a[x].fa=a[y].fa;
    a[y].ch[!mk]=a[x].ch[mk];
    a[a[x].ch[mk]].fa=y;
    a[y].fa=x;
    a[x].ch[mk]=y;
    ct(y);ct(x);
}
void splay(int x)
{
    int y,k=x,cnt=0;stacks[++cnt]=k;
    while (!isroot(k))
        stacks[++cnt]=a[k].fa,
        k=a[k].fa;
    for (int i=cnt;i;i--) pushdown(stacks[i]);
    while (!isroot(x))
    {
        y=a[x].fa;
        if (isroot(y))
        {
            int t=a[y].fa;
            if (a[y].ch[0]==x) rorate(x,1);
            else rorate(x,0);
            a[x].fa=t;
        }
        else if (a[a[y].fa].ch[0]==y)
        {
            if (a[y].ch[0]==x) rorate(y,1);
            else rorate(x,0);
            rorate(x,1);
        }
        else
        {
            if (a[y].ch[1]==x) rorate(y,0);
            else rorate(x,1);
            rorate(x,0);
        }
    }
}
void access(int x)
{
    for (int y=0;x;y=x,x=a[x].fa)
        splay(x),
        a[x].ch[1]=y,
        ct(x);
}
void link(int x,int y)
{
    access(x);
    splay(x);
    a[x].lazy^=1;
    a[x].fa=y;
    splay(x);
}
void cut(int x,int y)
{
    access(x);
    splay(x);
    a[x].lazy^=1;
    access(y);
    splay(y);
    a[y].ch[0]=a[x].fa=0;
}
main()
{
    n=in();
    for (int i=1;i<=n;i++)
    {
        x=in();
        a[i].fa=min(x+i,n+1);
        next[i]=a[i].fa;
        a[i].siz=1;
    }
    ct(n+1);
    m=in();
    while (m--)
    {
        opt=in();
        if (opt==1)
        {
            access(n+1);
            splay(n+1);
            a[n+1].lazy^=1;
            x=in();
            x++;
            access(x);
            splay(x);
            printf("%d\n",a[a[x].ch[0]].siz);
        }
        else
        {
            x=in();y=in();
            x++;
            cut(x,next[x]);
            next[x]=min(x+y,n+1);
            link(x,next[x]);
        }
    }
}

你可能感兴趣的:(【codevs2333】【BZOJ2002】弹飞绵羊,第一次的LCT)