记录编号 213114 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [NOI 2015]软件包管理器 最终得分 100
用户昵称 Gravatarstdafx.h 是否通过 通过
代码语言 C++ 运行时间 7.646 s
提交时间 2015-12-10 11:50:30 内存使用 6.77 MiB
显示代码纯文本
  1. #define lson l,mid,t
  2. #define rson mid+1,r,t|1
  3. #define cson l,r,rt
  4.  
  5. #define MAXN 100010UL
  6. #define MAXC 20UL
  7.  
  8. #include <cstdio>
  9. #include <cstring>
  10.  
  11. struct Edge{int v,nx;};
  12. Edge edge[MAXN];
  13. int n,m,ec,posl,posr,update_val,headlist[MAXN],fa[MAXN],son[MAXN],size[MAXN],cnt,id[MAXN],top[MAXN],mark[MAXN<<2],tree[MAXN<<2],out_sta[MAXN];
  14. char op[MAXC];
  15.  
  16. inline void Add_Edge(int u,int v){
  17. edge[++ec].v=v;
  18. edge[ec].nx=headlist[u];
  19. headlist[u]=ec;
  20. return;
  21. }
  22.  
  23. inline int in(){
  24. int x=0,c=getchar();
  25. while(c<'0'||c>'9') c=getchar();
  26. for(;c>='0'&&c<='9';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
  27. return x;
  28. }
  29.  
  30. void dfs(int p){
  31. size[p]|=1;
  32. for(int i=headlist[p];i;i=edge[i].nx){
  33. dfs(edge[i].v);
  34. size[p]+=size[edge[i].v];
  35. if(size[son[p]]<size[edge[i].v]) son[p]=edge[i].v;
  36. }
  37. return;
  38. }
  39.  
  40. void build_tree(int p,int tp){
  41. top[p]=tp;
  42. id[p]=++cnt;
  43. if(son[p]) build_tree(son[p],tp);
  44. for(int i=headlist[p];i;i=edge[i].nx)
  45. if(son[p]!=edge[i].v) build_tree(edge[i].v,edge[i].v);
  46. out_sta[p]=cnt;
  47. return;
  48. }
  49.  
  50. inline void Clear(int l,int r,int rt){
  51. if(l==r||mark[rt]==-1) return;
  52. int t=rt<<1,mid=(l+r)>>1;
  53. mark[t]=mark[t|1]=mark[rt];
  54. tree[t]=mark[rt]*(mid-l+1);
  55. tree[t|1]=mark[rt]*(r-mid);
  56. mark[rt]=-1;
  57. return;
  58. }
  59.  
  60. int Query(int l,int r,int rt){
  61. if(posl<=l&&posr>=r)
  62. return tree[rt];
  63. int t=rt<<1,mid=(l+r)>>1,Ans=0;
  64. Clear(cson);
  65. if(posl<=mid) Ans+=Query(lson);
  66. if(posr>mid) Ans+=Query(rson);
  67. return Ans;
  68. }
  69.  
  70. void Update(int l,int r,int rt){
  71. if(posl<=l&&posr>=r){
  72. mark[rt]=update_val;
  73. tree[rt]=(r-l+1)*update_val;
  74. return;
  75. }
  76. int t=rt<<1,mid=(l+r)>>1;
  77. Clear(cson);
  78. if(posl<=mid) Update(lson);
  79. if(posr>mid) Update(rson);
  80. tree[rt]=tree[t]+tree[t|1];
  81. return;
  82. }
  83.  
  84. inline int Q(int l,int r,int mk){
  85. if(l>r) return 0;
  86. posl=l,posr=r;
  87. if(mk) return r-l+1-Query(1,n,1);
  88. else return Query(1,n,1);
  89. }
  90.  
  91. inline void U(int l,int r,int ty){
  92. if(l>r) return;
  93. posl=l,posr=r,update_val=ty;
  94. Update(1,n,1);
  95. return;
  96. }
  97.  
  98. inline void Install(int p){
  99. int Ans=0;
  100. while(top[p]!=1){
  101. Ans+=Q(id[top[p]],id[p],1);
  102. U(id[top[p]],id[p],1);
  103. p=fa[top[p]];
  104. }
  105. Ans+=Q(1,id[p],1);
  106. U(1,id[p],1);
  107. printf("%d",Ans);
  108. return;
  109. }
  110.  
  111. inline void UnInstall(int p){
  112. printf("%d",Q(id[p],out_sta[p],0));
  113. U(id[p],out_sta[p],0);
  114. return;
  115. }
  116.  
  117. int main(){
  118. freopen("manager.in","r",stdin);
  119. freopen("manager.out","w",stdout);
  120. n=in();
  121. memset(mark,-1,sizeof(mark));
  122. for(int i=2;i<=n;i++) fa[i]=in()+1,Add_Edge(fa[i],i);
  123. dfs(1);build_tree(1,1);
  124. scanf("%d",&m);
  125. for(int i=1,tmp;i<=m;i++,puts("")){
  126. scanf("%s",op),tmp=in()+1;
  127. if(op[0]=='i') Install(tmp);
  128. else UnInstall(tmp);
  129. }
  130. return 0;
  131. }