显然链剖 然而只询问到根的信息,不用管lca,要好些很多(虽然我没那么写)

对于安装 查询和维护到根路径

对于卸载 查询和维护子树信息

因为链剖本身是用dfs序建的线段树,所以使得查询和修改子树非常方便。

  1. #include<iostream>
  2. #include<cstring>
  3. #include<cstdlib>
  4. #include<cstdio>
  5. #include<algorithm>
  6.  
  7. using namespace std;
  8.  
  9. const int Maxn=;
  10. int n;
  11. struct Data{
  12. int num[];
  13. Data(int a=,int b=) {num[]=a,num[]=b;}
  14. Data operator + (const Data&rhs) const {
  15. return Data(num[]+rhs.num[],num[]+rhs.num[]);
  16. }
  17. };
  18.  
  19. struct SegmentTree{
  20. Data da[Maxn*];
  21. int tag[Maxn*];
  22. int lft,rgt,w;
  23.  
  24. void add_tag(int s,int l,int r,int w) {
  25. if(w==-) return;
  26. da[s].num[w]=r-l+;
  27. da[s].num[w^]=;
  28. tag[s]=w;
  29. }
  30.  
  31. void down(int s,int l,int r) {
  32. if(tag[s]==- || l==r) return;
  33. int mid=(l+r)>>;
  34. add_tag(s<<,l,mid,tag[s]);
  35. add_tag(s<<|,mid+,r,tag[s]);
  36. tag[s]=-;
  37. }
  38.  
  39. void change(int s,int l,int r) {
  40. if(lft<=l && r<=rgt) {
  41. add_tag(s,l,r,w);
  42. return;
  43. }
  44. down(s,l,r);
  45. int mid=(l+r)>>;
  46. if(lft<=mid) change(s<<,l,mid);
  47. if(mid<rgt) change(s<<|,mid+,r);
  48. da[s] = da[s<<] + da[s<<|];
  49. }
  50. Data query(int s,int l,int r) {
  51. if(lft<=l&&r<=rgt) return da[s];
  52. down(s,l,r);
  53. int mid=(l+r)>>;
  54. if(rgt<=mid) return query(s<<,l,mid);
  55. if(mid<lft) return query(s<<|,mid+,r);
  56. return query(s<<,l,mid) + query(s<<|,mid+,r);
  57. }
  58. void build(int s,int l,int r) {
  59. if(l==r) {
  60. da[s]=Data(,);
  61. return;
  62. }
  63. int mid=(l+r)>>;
  64. build(s<<,l,mid);
  65. build(s<<|,mid+,r);
  66. da[s]=da[s<<]+da[s<<|];
  67. }
  68. }seg;
  69.  
  70. int sz[Maxn],fa[Maxn],son[Maxn],dep[Maxn];
  71.  
  72. struct Edge {
  73. int to;
  74. Edge*next;
  75. Edge(int to=,Edge*next=):to(to),next(next) {}
  76. }pool[Maxn*],*pis=pool,*fir[Maxn];
  77.  
  78. void AddEdge(int from,int to) {
  79. *pis=Edge(to,fir[from]);fir[from]=pis++;
  80. *pis=Edge(from,fir[to]);fir[to]=pis++;
  81. }
  82.  
  83. void dfs(int u) {
  84. sz[u] = ;
  85. son[u] = ;
  86. for(Edge*p=fir[u];p;p=p->next) {
  87. int v=p->to;
  88. if(v==fa[u]) continue;
  89. fa[v]=u;
  90. dep[v]=dep[u]+;
  91. dfs(v);
  92. sz[u]+=sz[v];
  93. if(sz[v]>sz[son[u]]) son[u]=v;
  94. }
  95. }
  96.  
  97. int pos[Maxn],top[Maxn],tm,end[Maxn];
  98.  
  99. void build(int u,int pre) {
  100. top[u] = pre;
  101. pos[u] = ++tm;
  102. if(son[u]) build(son[u],pre);
  103. for(Edge*p=fir[u];p;p=p->next) {
  104. int v=p->to;
  105. if(v==fa[u] || v==son[u]) continue;
  106. build(v,v);
  107. }
  108. end[u]=tm;
  109. }
  110.  
  111. Data query(int a,int b) {
  112. int ta=top[a],tb=top[b];
  113. Data ret;
  114. for(;ta!=tb;a=fa[ta],ta=top[a]) {
  115. if(dep[ta]<dep[tb]) swap(a,b) ,swap(ta,tb);
  116. seg.lft=pos[ta],seg.rgt=pos[a];
  117. ret=ret+seg.query(,,n);
  118. }
  119. if(dep[a]>dep[b]) swap(a,b);
  120. seg.lft=pos[a],seg.rgt=pos[b];
  121. Data tmp=seg.query(,,n);
  122. return ret+tmp;
  123. }
  124.  
  125. void change(int a,int b,int c) {
  126. int ta=top[a],tb=top[b];
  127. Data ret;
  128. for(;ta!=tb;a=fa[ta],ta=top[a]) {
  129. if(dep[ta]<dep[tb]) swap(a,b) ,swap(ta,tb);
  130. seg.lft=pos[ta],seg.rgt=pos[a];seg.w=c;
  131. seg.change(,,n);
  132. }
  133. if(dep[a]>dep[b]) swap(a,b);
  134. seg.lft=pos[a],seg.rgt=pos[b],seg.w=c;
  135. return seg.change(,,n);
  136. }
  137.  
  138. void init() {
  139. memset(seg.tag,-,sizeof seg.tag);
  140. scanf("%d",&n);
  141. for(int x,i=;i<n;i++) {
  142. scanf("%d",&x);
  143. AddEdge(i+,x+);
  144. }
  145. dfs();
  146. build(,);
  147. seg.build(,,n);
  148.  
  149. // seg.lft=1,seg.rgt=n,seg.w=0;change(1,1,n);
  150. }
  151.  
  152. void work() {
  153. int m,x;
  154. char opt[];
  155. for(scanf("%d",&m);m--;) {
  156. scanf("%s%d",opt,&x);x++;
  157. if(opt[]=='i') {
  158. printf("%d\n",query(x,).num[]);
  159. change(x,,);
  160. }else {
  161. seg.lft=pos[x],seg.rgt=end[x],seg.w=;
  162. printf("%d\n",seg.query(,,n).num[]);
  163. seg.change(,,n);
  164. }
  165. }
  166. }
  167.  
  168. int main() {
  169. freopen("manager.in","r",stdin);
  170. freopen("manager.out","w",stdout);
  171.  
  172. init();
  173. work();
  174.  
  175. return ;
  176. }

NOI2015 软件包管理器 manager的更多相关文章

  1. 洛谷 P2146 [NOI2015]软件包管理器 树链剖分

    目录 题面 题目链接 题目描述 输入输出格式 输入格式: 输出格式: 输入输出样例 输入样例#1: 输出样例#1: 输入样例#2: 输出样例#2: 说明 说明 思路 AC代码 总结 题面 题目链接 P ...

  2. BZOJ 4196: [Noi2015]软件包管理器 [树链剖分 DFS序]

    4196: [Noi2015]软件包管理器 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1352  Solved: 780[Submit][Stat ...

  3. [BZOJ4196][NOI2015]软件包管理器

    4196: [Noi2015]软件包管理器 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1040  Solved: 603[Submit][Stat ...

  4. Bzoj 4196: [Noi2015]软件包管理器 树链剖分

    4196: [Noi2015]软件包管理器 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 721  Solved: 419[Submit][Statu ...

  5. [NOI2015]软件包管理器

    4621 [NOI2015]软件包管理器  题目等级 : 钻石 Diamond   题目描述 Description Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过 ...

  6. BZOJ_4196_[Noi2015]软件包管理器_树链剖分

    BZOJ_4196_[Noi2015]软件包管理器_树链剖分 题意: Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助 ...

  7. bzoj 4196 [Noi2015]软件包管理器 (树链剖分+线段树)

    4196: [Noi2015]软件包管理器 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 2852  Solved: 1668[Submit][Sta ...

  8. 洛谷 P2146 [NOI2015]软件包管理器 解题报告

    P2146 [NOI2015]软件包管理器 题目描述 Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件源下载软 ...

  9. 【BZOJ4196】[Noi2015]软件包管理器 树链剖分

    [Noi2015]软件包管理器 树链剖分 Description Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从 ...

随机推荐

  1. Bridge 模式

    Bridge 模式将抽象和行为划分开来,各自独立,但能动态的结合.在面向对象设计的基本概念中,对象这个概念实际是由属性和行为两个部分组成的,属性我们可以认为是一种静止的,是一种抽象,一般情况下,行为是 ...

  2. 浅谈 trie树 及其实现

    定义:又称字典树,单词查找树或者前缀树,是一种用于快速检索的多叉树结构, 如英文字母的字典树是一个26叉树,数字的字典树是一个10叉树. 核心思想:是空间换时间.利用字符串的公共前缀来降低查询时间的开 ...

  3. Sublime Text 皮肤插件安装

    安装皮肤, 举例sodahttps://github.com/buymeasoda/soda-themectrl+shift+p => Package Control: Install Pack ...

  4. CentOS7下安装配置vncserver

    之前试了xmanager,不过好像和在centos6有很大不同,居然没成功,然后找到了vncserver,试了下,成了 参考:http://blog.csdn.net/jiangliqing1234/ ...

  5. c# winform 设置winform进入窗口后在文本框里的默认焦点

    c# winform 设置winform进入窗口后在文本框里的默认焦点 进入窗口后默认聚焦到某个文本框,两种方法: ①设置tabindex 把该文本框属性里的tabIndex设为0,焦点就默认在这个文 ...

  6. wndows常用命令

    1. 远程桌面 mstsc (Microsoft terminal services client)

  7. 《学习Opencv》第五章 习题6

    这是第五章 习题5.6的结合版,其中实现了摄像头抓拍功能,能够成功运行. #include "stdafx.h" #include "cv.h" #includ ...

  8. “layout_”下划线开头的属性

    观看幕课网的视频的收获 “layout_”下划线开头的属性都是交给父容器去处理的属性,如: android:layout_width="match_parent" android: ...

  9. 排他锁Lock

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  10. 转:.NET 环境中使用RabbitMQ

    原文来自于:http://blog.jobbole.com/83819/ 原文出处: 寒江独钓   欢迎分享原创到伯乐头条 在企业应用系统领域,会面对不同系统之间的通信.集成与整合,尤其当面临异构系统 ...