为数不多的一遍过的树链剖分
安装时询问,修改到root的链 删除时询问,修改子树
跑了8s好刺激qwq
/**************************************************************
Problem: 4196
User: syh0313
Language: C++
Result: Accepted
Time:8076 ms
Memory:15392 kb
****************************************************************/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#define lch a[n].lc
#define rch a[n].rc
using
namespace
std;
const
int
maxn=100010;
struct
da{
int
lc,rc,l,r,sum,tag;}a[maxn<<2];
int
n,q,st[maxn],to[maxn],nt[maxn],topt,x,root,cnt;
int
dep[maxn],rem[maxn],si[maxn],fa[maxn];
int
dfn[maxn],line[maxn],dfn_num,top[maxn];
bool
f[maxn];
char
s[20];
void
add(
int
x,
int
y)
{to[++topt]=y; nt[topt]=st[x]; st[x]=topt;}
void
dfs1(
int
x,
int
de)
{
f[x]=1; dep[x]=de; si[x]=1;
int
p=st[x],ma=0;
while
(p)
{
if
(!f[to[p]])
{
dfs1(to[p],de+1);
fa[to[p]]=x; si[x]+=si[to[p]];
if
(si[to[p]]>ma) {ma=si[to[p]]; rem[x]=to[p];}
}
p=nt[p];
}
}
void
dfs2(
int
x)
{
f[x]=1;
if
(rem[fa[x]]==x) top[x]=top[fa[x]];
else
top[x]=x;
dfn[x]=++dfn_num; line[dfn_num]=x;
if
(rem[x]) dfs2(rem[x]);
int
p=st[x];
while
(p)
{
if
(!f[to[p]]) dfs2(to[p]);
p=nt[p];
}
}
void
updata(
int
n) {a[n].sum=a[lch].sum+a[rch].sum;}
void
build_tree(
int
&n,
int
l,
int
r)
{
n=++cnt; a[n].l=l; a[n].r=r; a[n].tag=-1;
if
(l==r)
return
;
int
mid=(l+r)>>1;
build_tree(lch,l,mid); build_tree(rch,mid+1,r);
updata(n);
}
void
pushdown(
int
n)
{
if
(a[n].tag==-1)
return
;
a[lch].sum=(a[lch].r-a[lch].l+1)*a[n].tag;
a[rch].sum=(a[rch].r-a[rch].l+1)*a[n].tag;
a[lch].tag=a[rch].tag=a[n].tag; a[n].tag=-1;
}
void
tree_fz(
int
n,
int
L,
int
R,
int
l,
int
r,
int
k)
{
if
(L==l && R==r)
{a[n].tag=k; a[n].sum=(a[n].r-a[n].l+1)*k;
return
;}
pushdown(n);
int
mid=(L+R)>>1;
if
(r<=mid) tree_fz(lch,L,mid,l,r,k);
else
if
(l>=mid+1) tree_fz(rch,mid+1,R,l,r,k);
else
tree_fz(lch,L,mid,l,mid,k),tree_fz(rch,mid+1,R,mid+1,r,k);
updata(n);
}
void
qfz(
int
x,
int
y,
int
k)
{
while
(top[x]!=top[y])
{
if
(dep[top[x]]<dep[top[y]]) swap(x,y);
tree_fz(root,1,n,dfn[top[x]],dfn[x],k);
x=fa[top[x]];
}
if
(dfn[x]>dfn[y]) swap(x,y);
tree_fz(root,1,n,dfn[x],dfn[y],k);
return
;
}
int
qury(
int
n,
int
L,
int
R,
int
l,
int
r)
{
if
(L==l && R==r)
return
a[n].sum;
pushdown(n);
int
mid=(L+R)>>1;
if
(r<=mid)
return
qury(lch,L,mid,l,r);
else
if
(l>=mid+1)
return
qury(rch,mid+1,R,l,r);
else
return
qury(lch,L,mid,l,mid)+qury(rch,mid+1,R,mid+1,r);
updata(n);
}
int
qsum(
int
x,
int
y)
{
int
sum=0;
while
(top[x]!=top[y])
{
if
(dep[top[x]]<dep[top[y]]) swap(x,y);
sum+=qury(root,1,n,dfn[top[x]],dfn[x]);
x=fa[top[x]];
}
if
(dfn[x]>dfn[y]) swap(x,y);
sum+=qury(root,1,n,dfn[x],dfn[y]);
return
sum;
}
int
main()
{
scanf
(
"%d"
,&n);
for
(
int
i=1;i<=n-1;i++)
scanf
(
"%d"
,&x),add(x,i);
dfs1(0,1);
memset
(f,0,
sizeof
f); dfs2(0);
build_tree(root,1,n);
scanf
(
"%d"
,&q);
while
(q--)
{
scanf
(
"%s%d"
,s,&x);
if
(s[0]==
'i'
)
{
printf
(
"%d\n"
,max(0,dep[x]-qsum(0,x)));
qfz(0,x,1);
}
else
{
printf
(
"%d\n"
,qury(root,1,n,dfn[x],dfn[x]+si[x]-1));
tree_fz(root,1,n,dfn[x],dfn[x]+si[x]-1,0);
}
}
return
0;
}