【[HNOI2010]弹飞绵羊】LCT乱搞题
最近新学了LCT,又可以刷一堆水(keng)题了,真是开心啊
传送门: https://www.luogu.org/problemnew/show/P3203
感觉还是很显然吧,直接将这个(点)与(点+劲度系数)的点连接起来,
同时考虑建一个空结点n+1(编号0不好处理,于是所有编号向上平移一个单位),意为所有的绵羊到这个地方就能够被弹飞
如果连接的时候i+k<=n就连不然就和n+1连接起来
每一次询问操作,setroot(x) access(n+1) splay(n+1),答案就是siz[n+1]-1
而每次进行修改劲度系数的时候,不只是光要连,还要将原来的边删掉。 就可以了(同时记得编号连接不大于n+1规定)
就这样搞定了,开始痛苦地调试罢!
cheer!
#include<bits/stdc++.h>
#define zig(x) zigzag(x,1)
#define zag(x) zigzag(x,2)
using namespace std;
const int maxn=200005;
int n,m,rev[maxn],ls[maxn],rs[maxn],fa[maxn],jingdu[maxn],siz[maxn];
bool isroot(int x) { return ls[fa[x]]!=x&&rs[fa[x]]!=x; }
void putup(int x)
{
siz[x]=siz[ls[x]]+siz[rs[x]]+1;
}
void zigzag(int x,int knd)
{
int y=fa[x],z=fa[y];
if(!isroot(y))
{
if(ls[z]==y) ls[z]=x;
else rs[z]=x;
}
fa[x]=z; fa[y]=x;
if(knd==1)
{
ls[y]=rs[x];
fa[ls[y]]=y;
rs[x]=y;
}
else
{
rs[y]=ls[x];
fa[rs[y]]=y;
ls[x]=y;
}
putup(y); putup(x);
}
void putdowm(int x)
{
if(!rev[x]) return;
swap(ls[x],rs[x]); rev[ls[x]]^=1; rev[rs[x]]^=1;
rev[x]=0;
}
int sta[maxn];
void splay(int x)
{
int top=0; sta[++top]=x;
for(int i=x;!isroot(i);i=fa[i]) { sta[++top]=fa[i]; }
while(top) putdowm(sta[top--]);
while(!isroot(x))
{
int y=fa[x],z=fa[y];
if(isroot(y))
{
if(ls[y]==x) zig(x);
else zag(x);
}
else
{
if(ls[z]==y)
{
if(ls[y]==x) { zig(y); zig(x); }
else { zag(x); zig(x); }
}
else
{
if(rs[y]==x) { zag(y); zag(x); }
else { zig(x); zag(x); }
}
}
}
}
void acc(int x)
{
for(int y=0;x;y=x,x=fa[x])
{
splay(x);
rs[x]=y;
putup(x);
}
}
void setroot(int x)
{
acc(x); splay(x); rev[x]^=1;
}
void link(int a,int b)
{
setroot(a); fa[a]=b;
}
void cut(int a,int b)
{
setroot(a); acc(b); splay(b);
ls[b]=fa[a]=0;
}
int getroot(int a)
{
acc(a); splay(a);
while(ls[a]) a=ls[a];
return a;
}
int ans(int x)
{
setroot(x); acc(n+1); splay(n+1); return siz[n+1]-1;
}
void change(int x,int y)
{
cut(x,min(jingdu[x]+x,n+1)); jingdu[x]=y; link(x,min(x+jingdu[x],n+1));
}
int main()
{
int x,y,z;
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&jingdu[i]);
link(i,min(jingdu[i]+i,n+1));
}
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
scanf("%d",&x);
if(x==1)
{
scanf("%d",&y); ++y;
printf("%d\n",ans(y));
}
else
{
scanf("%d%d",&y,&z); ++y;
change(y,z);
}
}
}

浙公网安备 33010602011771号