记录编号 498778 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [NOI 2015]软件包管理器 最终得分 100
用户昵称 GravatarAntiLeaf 是否通过 通过
代码语言 C++ 运行时间 3.251 s
提交时间 2018-06-21 21:35:34 内存使用 7.17 MiB
显示代码纯文本
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn=100005;
void dfs1(int);
void dfs2(int);
int install(int);
int uninstall(int);
void modify(int,int,int);
void query(int,int,int);
void pushdown(int,int,int,int);
vector<int>G[maxn];
int lazy[maxn<<2],sm[maxn<<2];
int p[maxn],d[maxn],size[maxn],son[maxn],top[maxn],L[maxn],R[maxn];
char c[15];
int n,m,tim=0,s,t,tmp;
int main(){
	freopen("manager.in","r",stdin);
	freopen("manager.out","w",stdout);
	memset(lazy,-1,sizeof(lazy));
	scanf("%d",&n);
	for(int i=2;i<=n;i++){
		scanf("%d",&p[i]);
		G[++p[i]].push_back(i);
	}
	dfs1(1);
	dfs2(1);
	scanf("%d",&m);
	while(m--){
		int x;
		scanf("%s%d",c,&x);
		x++;
		if(*c=='i')printf("%d\n",install(x));
		else printf("%d\n",uninstall(x));
	}
	return 0;
}
void dfs1(int x){
	d[x]=d[p[x]]+1;
	size[x]=1;
	for(int i=0;i<(int)G[x].size();i++){
		dfs1(G[x][i]);
		size[x]+=size[G[x][i]];
		if(size[G[x][i]]>size[son[x]])son[x]=G[x][i];
	}
}
void dfs2(int x){
	top[x]=(x==son[p[x]]?top[p[x]]:x);
	L[x]=++tim;
	if(son[x])dfs2(son[x]);
	for(int i=0;i<(int)G[x].size();i++)
		if(G[x][i]!=son[x])dfs2(G[x][i]);
	R[x]=tim;
}
int install(int x){
	int ans=0;
	while(x){
		s=L[top[x]];
		t=L[x];
		tmp=0;
		query(1,n,1);
		ans+=d[x]-d[top[x]]+1-tmp;
		tmp=1;
		modify(1,n,1);
		x=p[top[x]];
	}
	return ans;
}
int uninstall(int x){
	s=L[x];
	t=R[x];
	tmp=0;
	query(1,n,1);
	int ans=tmp;
	tmp=0;
	modify(1,n,1);
	return ans;
}
void modify(int l,int r,int rt){
	if(s<=l&&t>=r){
		lazy[rt]=tmp;
		sm[rt]=(r-l+1)*tmp;
		return;
	}
	int mid=(l+r)>>1;
	pushdown(l,r,mid,rt);
	if(s<=mid)modify(l,mid,rt<<1);
	if(t>mid)modify(mid+1,r,rt<<1|1);
	sm[rt]=sm[rt<<1]+sm[rt<<1|1];
}
void query(int l,int r,int rt){
	if(s<=l&&t>=r){
		tmp+=sm[rt];
		return;
	}
	int mid=(l+r)>>1;
	pushdown(l,r,mid,rt);
	if(s<=mid)query(l,mid,rt<<1);
	if(t>mid)query(mid+1,r,rt<<1|1);
}
void pushdown(int l,int r,int mid,int rt){
	if(lazy[rt]==-1)return;
	sm[rt<<1]=lazy[rt]*(mid-l+1);
	sm[rt<<1|1]=lazy[rt]*(r-mid);
	lazy[rt<<1]=lazy[rt<<1|1]=lazy[rt];
	lazy[rt]=-1;
}