记录编号 312259 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [NOI 2015]软件包管理器 最终得分 100
用户昵称 Gravatarcdcq 是否通过 通过
代码语言 C++ 运行时间 7.963 s
提交时间 2016-09-25 21:23:38 内存使用 92.36 MiB
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
int read(){int z=0,mark=1;  char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')mark=-1;  ch=getchar();}
	while(ch>='0'&&ch<='9'){z=(z<<3)+(z<<1)+ch-'0';  ch=getchar();}
	return z*mark;
}
struct ddd{int next,y;}e[110000];int LINK[110000],ltop=0;
inline void insert(int x,int y){e[++ltop].next=LINK[x];LINK[x]=ltop;e[ltop].y=y;}
int n,m;
int size[110000],deep[110000],father[110000],big_child[110000],top[110000],n_value[110000];
int dfs_xv[110000],fan_xv[110000],er_xv[110000],xv_cnt=-1;//注意因为从0开始,所以总共有7个点,但是编号只到6
void dfs1(int x,int _father,int _deep){
	father[x]=_father,deep[x]=_deep,size[x]=1;
	int max_size=0,max_child=-1;//注意0有意义
	for(int i=LINK[x];i;i=e[i].next)if(e[i].y!=father[x]){
		dfs1(e[i].y,x,_deep+1);
		size[x]+=size[e[i].y];
		if(size[e[i].y]>max_size)  max_size=size[e[i].y],max_child=e[i].y;
	}
	big_child[x]=max_child;
}
void dfs2(int x,int _top){
	top[x]=_top;  dfs_xv[++xv_cnt]=x;  fan_xv[x]=xv_cnt;
	if(big_child[x]!=-1)  dfs2(big_child[x],_top);//注意-1
	for(int i=LINK[x];i;i=e[i].next)if(e[i].y!=father[x] && e[i].y!=big_child[x])
		dfs2(e[i].y,e[i].y);
	er_xv[x]=xv_cnt;
}
struct dcd{int sleft,sright,mid,svalue,delta;}tree[5100000];
void stev(int x){  tree[x].svalue=tree[x].delta*(tree[x].sright-tree[x].sleft+1);}//sxysxy_orz
void get_SegmentTree(int x,int _left,int _right){
	tree[x].sleft=_left,tree[x].sright=_right,tree[x].mid=(_left+_right)>>1;
	tree[x].svalue=tree[x].delta=0;
	if(_left!=_right)  get_SegmentTree(x<<1,_left,tree[x].mid),get_SegmentTree(x<<1|1,tree[x].mid+1,_right);
}
int search(int x,int _left,int _right){
	if(tree[x].sleft==_left && tree[x].sright==_right)  return tree[x].svalue;
	else{
		if(tree[x].delta!=-1){
			tree[x<<1].delta=tree[x<<1|1].delta=tree[x].delta;  tree[x].delta=-1;//注意这里并不是加上,而是设置为,注意-1 (sxysxy_orz
			stev(x<<1),stev(x<<1|1);
			tree[x].delta=-1;
		}
		if(_left<=tree[x].mid && _right>tree[x].mid)  return search(x<<1,_left,tree[x].mid)+search(x<<1|1,tree[x].mid+1,_right);
		else if(_right<=tree[x].mid)  return search(x<<1,_left,_right);
		else  return search(x<<1|1,_left,_right);
	}
}
void buff(int x,int _left,int _right,int z){
	if(tree[x].sleft==_left && tree[x].sright==_right)  tree[x].delta=z,stev(x);
	else{
		if(tree[x].delta!=-1){
			tree[x<<1].delta=tree[x<<1|1].delta=tree[x].delta;  tree[x].delta=-1;
			stev(x<<1),stev(x<<1|1);
			tree[x].delta=-1;
		}
		if(_left<=tree[x].mid && _right>tree[x].mid)  buff(x<<1,_left,tree[x].mid,z),buff(x<<1|1,tree[x].mid+1,_right,z);
		else if(_right<=tree[x].mid)  buff(x<<1,_left,_right,z);
		else  buff(x<<1|1,_left,_right,z);
		tree[x].svalue=tree[x<<1].svalue+tree[x<<1|1].svalue;
	}
}
int install(int x){
	int ans=0;
	while(x!=-1){
		ans+=fan_xv[x]-fan_xv[top[x]]+1-search(1,fan_xv[top[x]],fan_xv[x]);
		buff(1,fan_xv[top[x]],fan_xv[x],1);
		//x=father[x]  我是傻逼qaqqqqqqqqqqqqqqqqqqqq
		x=father[top[x]];
	}
	return ans;
}
int uninstall(int x){
	int ans=search(1,fan_xv[x],er_xv[x]);
	buff(1,fan_xv[x],er_xv[x],0);
	return ans;
}
int main(){
	/*freopen("ddd.in","r",stdin);
	freopen("ddd.out","w",stdout);*/
	freopen("manager.in","r",stdin);
	freopen("manager.out","w",stdout);
	cin>>n;
	for(int i=1;i<n;i++)  insert(read(),i),n_value[i]=0;
	dfs1(0,-1,1),dfs2(0,0),get_SegmentTree(1,0,n-1);
	cin>>m;
	char ch;  int _id;
	while(m --> 0){//趋向于
		ch=getchar(); 
	   	while(ch!='i' && ch!='u')  ch=getchar();
		if(ch=='i'){
			for(int i=1;i<=6;i++)  ch=getchar();
			_id=read();
			printf("%d\n",install(_id));
		}
		else{
			for(int i=1;i<=8;i++)  ch=getchar();
			_id=read();
			printf("%d\n",uninstall(_id));
		}
	}
	return 0;
}