[bzoj] 2002 弹飞绵羊 || LCT

原题

简单的LCT练习题。
我们发现对于一个位置x,他只能跳到位置x+k,也就是唯一的父亲去。加入我们将弹飞的绵羊定义为跳到了n+1,那么这就形成了一棵树。而因为要修改k,所以这颗树是动态连边的,那么LCT就可以解决了。
至于询问,我们把n+1变成根,然后access(x)将x到n+1的路径变为实路径,splay(x),因为每次是向父亲弹,所以sze[ls[x]]即为答案。
//想知道为什么不是sze[x]-1

AC代码:

#include<cstdio>
#include<algorithm>
#define N 200010
#define which(u) (ls[fa[(u)]]==(u))
#define isroot(u) (!fa[(u)] || (ls[fa[(u)]]!=(u) && rs[fa[u]]!=(u)))
using namespace std;
int n,m,fa[N],ls[N],rs[N],a[N],sze[N];
bool rev[N];
char s[20];

void update(int x)
{
    sze[x]=1;
    if (ls[x]) sze[x]+=sze[ls[x]];
    if (rs[x]) sze[x]+=sze[rs[x]];
}

void rotate(int u)
{
    int v=fa[u],w=fa[v],b=which(u)?rs[u]:ls[u];
    if (!isroot(v)) (which(v)?ls[w]:rs[w])=u;
    which(u)?(ls[v]=b,rs[u]=v):(rs[v]=b,ls[u]=v);
    fa[u]=w,fa[v]=u;
    if (b) fa[b]=v;
    if (v) update(v);
    if (u) update(u);
}

void pushdown(int u)
{
    if (!rev[u]) return ;
    rev[ls[u]]^=1;
    rev[rs[u]]^=1;
    swap(ls[u],rs[u]);
    rev[u]=0;
}

void splay(int u)
{
    static int stk[N],top;
    stk[top=1]=u;
    while (!isroot(stk[top])) stk[top+1]=fa[stk[top]],top++;
    while (top) pushdown(stk[top--]);
    while (!isroot(u))
    {
	if (!isroot(fa[u]))
	{
	    if (which(u)==which(fa[u])) rotate(fa[u]);
	    else rotate(u);
	}
	rotate(u);
    }
}

void access(int u)
{
    int v=0;
    while (u)
    {
	splay(u);
	rs[u]=v;
	v=u;
	u=fa[u];
    }
}

void makeroot(int u)
{
    access(u);
    splay(u);
    rev[u]^=1;
}

void link(int u,int v)
{
    makeroot(v);
    fa[v]=u;
}

void cut(int u,int v)
{
    makeroot(u);
    access(v);
    splay(v);
    ls[v]=fa[u]=0;
}

int query(int x)
{
    makeroot(n+1);
    access(x);
    splay(x);
    return sze[ls[x]];
}

int main()
{
    scanf("%d",&n);
    for (int i=1,x;i<=n;i++)
    {
	scanf("%d",&x);
	a[i]=(i+x<=n)?i+x:n+1;
	fa[i]=a[i];
	sze[i]=1;
    }
    sze[n+1]=1;
    scanf("%d",&m);
    while (m--)
    {
	int op,x,y;
	scanf("%d%d",&op,&x);
	++x;
	if (op==1)
	    printf("%d\n",query(x));
	else
	{
	    scanf("%d",&y);
	    cut(x,a[x]);
	    a[x]=(x+y<=n)?x+y:n+1;
	    link(x,a[x]);
	}
    }
    return 0;
}
posted @ 2018-02-25 10:40  Mrha  阅读(166)  评论(0编辑  收藏  举报