弹飞绵羊
链接:https://www.luogu.org/problemnew/show/P3203
题解:
lct模板题
代码:
#include <bits/stdc++.h>
using namespace std;
#define maxn 300000
int n,m,num,root,fa[maxn],leftson[maxn],rightson[maxn];
int count2[maxn],v[maxn];
bool rev[maxn];
void down(int x)
{
if (!rev[x]) return;
swap(leftson[x],rightson[x]); rev[x]=0;
rev[leftson[x]]^=1; rev[rightson[x]]^=1;
}
void updata(int x)
{
down(x);
count2[x]=count2[leftson[x]]+count2[rightson[x]]+1;
}
void pushr(int x)
{
rev[x]^=1;
}
bool pd(int x)
{
int y=fa[x];
if (leftson[y]!=x&&rightson[y]!=x) return(false);
else return(true);
}
void rotate(int x,int y)
{
int father=fa[x];
if (y==1)
{
rightson[father]=leftson[x];
if (leftson[x]) fa[leftson[x]]=father;
} else
{
leftson[father]=rightson[x];
if (rightson[x]) fa[rightson[x]]=father;
}
fa[x]=fa[father];
if (pd(father))
{
if (leftson[fa[father]]==father)
leftson[fa[father]]=x; else
rightson[fa[father]]=x;
}
fa[father]=x;
if (y==1) leftson[x]=father; else rightson[x]=father;
updata(father); updata(x);
}
void dfs(int x)
{
if (pd(x)) dfs(fa[x]);
down(x);
}
void splay(int x)
{
dfs(x);
int father=fa[x];
while (pd(x))
{
if (!pd(father))
{
if (x==leftson[father]) rotate(x,2);
else rotate(x,1);
} else
{
if (father==leftson[fa[father]])
{
if (x==leftson[father])
rotate(father,2),rotate(x,2);
else rotate(x,1),rotate(x,2);
} else
{
if (x==rightson[father])
rotate(father,1),rotate(x,1);
else rotate(x,2),rotate(x,1);
}
}
father=fa[x];
}
}
void access(int x)
{
for (int y=0;x;y=x,x=fa[x])
splay(x),rightson[x]=y,updata(x);
}
void makeroot(int x)
{
access(x);
splay(x);
pushr(x);
}
int findroot(int x)
{
access(x);
splay(x);
while (leftson[x]) x=leftson[x];
return x;
}
void split(int x,int y)
{
makeroot(x);
access(y);
splay(y);
}
void link(int x,int y)
{
makeroot(x);
if (findroot(y)!=x) fa[x]=y;
}
void cut(int x,int y)
{
makeroot(x);
if (findroot(y)==x&&fa[x]==y)
{
fa[x]=leftson[y]=0;
updata(y);
}
}
int main()
{
freopen("noip.in","r",stdin);
freopen("noip.out","w",stdout);
cin>>n;
int x,y;
for (int i=0;i<=n-1;i++)
{
cin>>x;
if (x+i<n) link(i+1,x+i+1),v[i]=x+i;
else link(i+1,n+1),v[i]=n;
}
cin>>m; int c;
while (m--)
{
cin>>c;
if (c==1)
{
cin>>x;
split(x+1,n+1);
cout<<count2[n+1]-1<<endl;
}
if (c==2)
{
cin>>x>>y;
cut(x+1,v[x]+1);
if (x+y<n) link(x+1,x+y+1),v[x]=x+y;
else link(x+1,n+1),v[x]=n;
}
}
return 0;
}