记录编号 |
471057 |
评测结果 |
AAAAAAAAAAAAAAAAAAAA |
题目名称 |
[NOI 2015]软件包管理器 |
最终得分 |
100 |
用户昵称 |
Fisher. |
是否通过 |
通过 |
代码语言 |
C++ |
运行时间 |
2.363 s |
提交时间 |
2017-11-05 20:04:47 |
内存使用 |
7.18 MiB |
显示代码纯文本
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <vector>
using namespace std;
/*
安装:
从该点加到根,一共加了多少个
卸载:
该点包括该点子树,全减,一共减了多少个;
本来就有的就不加;
本来就没的就不减;
不加不减:(不算贡献);
*/
const int maxn=100010;
int n,m;
vector<int>t[maxn];
int tot,sz[maxn],dep[maxn],fa[maxn],son[maxn],top[maxn],id[maxn],pre[maxn];
inline void dfs1(int u,int f,int d){
sz[u]=1;fa[u]=f;dep[u]=d;
int len=t[u].size();
for(int i=0;i<len;i++){
int v=t[u][i];
if(v==f)continue;
dfs1(v,u,d+1);
sz[u]+=sz[v];
if(!son[u]||sz[son[u]]<sz[v])son[u]=v;
}
}
inline void dfs2(int u,int tou){
top[u]=tou;id[u]=++tot;pre[tot]=u;
if(!son[u])return ;
dfs2(son[u],tou);
int len=t[u].size();
for(int i=0;i<len;i++){
int v=t[u][i];
if(v!=fa[u]&&v!=son[u])dfs2(v,v);
}
}
int sum[maxn<<2],lazy[maxn<<2];
int ans=0;
inline void update(int o,int l,int r){
int m=(l+r)>>1,ls=o<<1,rs=ls|1;
int lan=lazy[o];
lazy[o]=0;
if(lan==1){
sum[ls]=m-l+1;
sum[rs]=r-m;
lazy[ls]=1;
lazy[rs]=1;
}
else{
sum[ls]=sum[rs]=0;
lazy[ls]=lazy[rs]=-1;
}
}
inline void change(int o,int l,int r,int nl,int nr,int v){
if(l>=nl&&r<=nr){
if(v==1){
if(!sum[o]){sum[o]=r-l+1;ans+=sum[o];lazy[o]=1;return;}
if(sum[o]!=r-l+1){ans-=sum[o];sum[o]=r-l+1;ans+=sum[o];lazy[o]=1;return;}
return;
}
else{
if(sum[o]==r-l+1){ans+=sum[o];lazy[o]=-1;sum[o]=0;return;}
if(sum[o]!=r-l+1){ans+=sum[o];lazy[o]=-1;sum[o]=0;return;}
return;
}
}
int m=(l+r)>>1,ls=o<<1,rs=ls|1;
if(lazy[o]!=0)update(o,l,r);
if(m>=nl)change(ls,l,m,nl,nr,v);
if(m<nr)change(rs,m+1,r,nl,nr,v);
sum[o]=sum[ls]+sum[rs];
}
inline void treeadd(int x,int y,int val){
int u=top[x],v=top[y];
while(u!=v){
if(dep[u]<dep[v])swap(u,v),swap(x,y);
change(1,1,n,id[u],id[x],val);
x=fa[u];u=top[x];
}
if(dep[x]>dep[y])swap(x,y);
change(1,1,n,id[x],id[y],val);
}
char ru[10];
int main(){
freopen("manager.in","r",stdin);
freopen("manager.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<n;i++){
int f;
scanf("%d",&f);
f++;
t[f].push_back(i+1);
}
dfs1(1,0,1);
dfs2(1,1);
scanf("%d",&m);
for(int i=1;i<=m;i++){
int pos;
scanf("%s%d",ru,&pos);
pos++;
ans=0;
if(ru[0]=='i'){
treeadd(pos,1,1);
printf("%d\n",ans);
}
else{
change(1,1,n,id[pos],id[pos]+sz[pos]-1,-1);
printf("%d\n",ans);
}
}
return 0;
}