传送门1
传送门2
写在前面:感冒,在家休养,已陷入动物城不能自拔
思路:真的是莫名其妙就A了……加了个lazy标记什么的而且用了一些奇怪姿势的线段树?删一个包就是对它的子树进行统计,计算有多少个已安装的子节点,安一个包就是看它到根的路径上有多少没安装过的包(其实可以一直找父亲直到有安装过的?),po主反正是闲的蛋疼乱搞了一坨,在BZOJ上跑了9s+……
注意:如果你像我一样蛋疼的话lazy标记加的时候最好小心些
代码:
#include<bits/stdc++.h>
using namespace std;
int tot,n,x,q,cnt;
int first[100010],fa[100010],son[100010],pre[100010],dep[100010],siz[100010],top[100010],L[100010],R[100010];
char ch;
struct os
{
int u,v,next;
}e[200010];
struct node
{
int lazy,sum;
}tree[800010];
void add(int x,int y)
{
e[++tot].u=x;
e[tot].v=y;
e[tot].next=first[x];
first[x]=tot;
}
void pushdown(int now,int l,int r)
{
if (!tree[now].lazy) return;
int mid=(l+r)>>1;
tree[now<<1].sum=(tree[now].lazy-1)*(mid-l+1);
tree[now<<1].lazy=tree[now].lazy;
tree[now<<1|1].sum=(tree[now].lazy-1)*(r-mid);
tree[now<<1|1].lazy=tree[now].lazy;
tree[now].lazy=0;
}
void dfs1(int now)
{
siz[now]=1;
for (int i=first[now];i;i=e[i].next)
if (e[i].v!=fa[now])
{
fa[e[i].v]=now;
dep[e[i].v]=dep[now]+1;
dfs1(e[i].v);
if (siz[e[i].v]>siz[son[now]]) son[now]=e[i].v;
siz[now]+=siz[e[i].v];
}
}
void dfs2(int now,int tp)
{
L[now]=++cnt;
pre[cnt]=now;
top[now]=tp;
if (son[now]) dfs2(son[now],tp);
for (int i=first[now];i;i=e[i].next)
if (e[i].v!=son[now]&&e[i].v!=fa[now])
dfs2(e[i].v,e[i].v);
R[now]=cnt;
}
void update(int now,int begin,int end,int l,int r,int flag)//flag是打标记用的,可以随便搞搞
{
if (l<=begin&&end<=r)
{
tree[now].lazy=flag+1;
tree[now].sum=(end-begin+1)*flag;
return;
}
pushdown(now,begin,end);
int mid=(begin+end)>>1;
if (l<=mid) update(now<<1,begin,mid,l,r,flag);
if (r>mid) update(now<<1|1,mid+1,end,l,r,flag);
tree[now].sum=tree[now<<1].sum+tree[now<<1|1].sum;
}
int get(int now,int begin,int end,int l,int r)
{
if (l<=begin&&end<=r) return tree[now].sum;
pushdown(now,begin,end);
int ans=0,mid=(begin+end)>>1;
if (mid>=l) ans+=get(now<<1,begin,mid,l,r);
if (mid<r) ans+=get(now<<1|1,mid+1,end,l,r);
return ans;
}
void solve(int l,int r)
{
int ans,f1=top[l],f2=top[r];
ans=dep[l]-dep[r]+1;//某个点到根路径上所经过的点数就是深度之差+1
while (f1!=f2)
{
if (dep[f1]<dep[f2]) swap(f1,f2),swap(l,r);
ans-=get(1,1,cnt,L[f1],L[l]);
update(1,1,cnt,L[f1],L[l],1);
l=fa[f1];f1=top[l];
}
if (dep[l]>dep[r]) swap(l,r);
ans-=get(1,1,cnt,L[l],L[r]);
update(1,1,cnt,L[l],L[r],1);
printf("%d\n",ans);
}
main()
{
scanf("%d",&n);
for (int i=2;i<=n;i++)
scanf("%d",&x),
add(x+1,i),
add(i,x+1);
dfs1(1);
dfs2(1,1);
scanf("%d",&q);
while (q--)
{
ch=getchar();
while (ch!='i'&&ch!='u') ch=getchar();
while (getchar()!=' ');
scanf("%d",&x);
x++;
if (ch=='i') solve(x,1);
else
{
int ans=get(1,1,cnt,L[x],R[x]);
printf("%d\n",ans);
update(1,1,cnt,L[x],R[x],0);
}
}
}