点此看题面

大致题意: 有\(n\)个软件包,它们的依赖关系形成一棵树。现在,问你安装或卸载一个软件包,会影响多少个软件包的安装状态。

树链剖分

这道题应该是 树链剖分 算法比较入门的题目吧。

对于安装操作

我们对安装和卸载两种操作分别处理。

首先,让我们来看一看安装操作应该如何实现。

考虑到要安装一个软件包,就要把它所依赖的软件包,它的依赖所依赖的软件包,一直到\(0\)号软件包,全部安装。

如果将题目中给出的关系看成一棵树,那么也就是要把这个软件包到\(0\)号节点(即 根节点 )的路径上的所有软件包全部安装。

用树链剖分应该可以轻松做到这一点。

对于卸载操作

我们再来看看如何实现卸载操作。

考虑卸掉一个软件包,那么所有依赖于它的软件包将全被卸载,所有依赖于依赖于它的软件包的软件包,也将全被卸载,以此类推。

不难想到,这就相当于把以这个软件包为根的子树内的所有软件包给卸载了。

用树链剖分应该也能很轻松做到这一点。

代码

  1. #include<bits/stdc++.h>
  2. #define max(x,y) ((x)>(y)?(x):(y))
  3. #define min(x,y) ((x)<(y)?(x):(y))
  4. #define abs(x) ((x)<0?-(x):(x))
  5. #define LL long long
  6. #define ull unsigned long long
  7. #define swap(x,y) (x^=y,y^=x,x^=y)
  8. #define N 100000
  9. #define add(x,y) (e[++ee].nxt=lnk[x],e[lnk[x]=ee].to=y)
  10. using namespace std;
  11. int n,ee=0,lnk[N+5];
  12. struct edge
  13. {
  14. int to,nxt;
  15. }e[2*N+5];
  16. class FIO
  17. {
  18. private:
  19. #define Fsize 100000
  20. #define tc() (FinNow==FinEnd&&(FinEnd=(FinNow=Fin)+fread(Fin,1,Fsize,stdin),FinNow==FinEnd)?EOF:*FinNow++)
  21. #define pc(ch) (FoutSize<Fsize?Fout[FoutSize++]=ch:(fwrite(Fout,1,FoutSize,stdout),Fout[(FoutSize=0)++]=ch))
  22. int f,FoutSize,OutputTop;char ch,Fin[Fsize],*FinNow,*FinEnd,Fout[Fsize],OutputStack[Fsize];double w;
  23. public:
  24. FIO() {FinNow=FinEnd=Fin;}
  25. inline void read(int &x) {x=0,f=1;while(!isdigit(ch=tc())) f=ch^'-'?1:-1;while(x=(x<<3)+(x<<1)+(ch&15),isdigit(ch=tc()));x*=f;}
  26. inline void read_char(char &x) {while(isspace(x=tc()));}
  27. inline void read_string(string &x) {x="";while(isspace(ch=tc()));while(x+=ch,!isspace(ch=tc()));}
  28. inline void write(int x) {if(!x) return (void)pc('0');if(x<0) pc('-'),x=-x;while(x) OutputStack[++OutputTop]=x%10+48,x/=10;while(OutputTop) pc(OutputStack[OutputTop]),--OutputTop;}
  29. inline void write_char(char x) {pc(x);}
  30. inline void write_string(string x) {register int i,len=x.length();for(i=0;i<len;++i) pc(x[i]);}
  31. inline void end() {fwrite(Fout,1,FoutSize,stdout);}
  32. }F;
  33. class TreeChainDissection//树链剖分模板
  34. {
  35. private:
  36. #define PushUp(x) (Sum[x]=Sum[x<<1]+Sum[x<<1|1])
  37. #define PushDown(x,ln,rn) ((~flag[x]?(flag[x]?(Sum[x<<1]=ln,Sum[x<<1|1]=rn,flag[x<<1]=flag[x<<1|1]=1):(Sum[x<<1]=Sum[x<<1|1]=flag[x<<1]=flag[x<<1|1]=0)):0),flag[x]=-1)
  38. int d,fa[N+5],son[N+5],sz[N+5],Top[N+5],dfn[N+5],fac[N+5],Depth[N+5],Sum[N<<2],flag[N<<2];
  39. inline void dfs1(int x)//第一遍dfs预处理
  40. {
  41. register int i;
  42. for(sz[x]=1,i=lnk[x];i;i=e[i].nxt)
  43. {
  44. if(!(fa[x]^e[i].to)) continue;
  45. fa[e[i].to]=x,Depth[e[i].to]=Depth[x]+1,dfs1(e[i].to),sz[x]+=sz[e[i].to];
  46. if(sz[e[i].to]>sz[son[x]]) son[x]=e[i].to;
  47. }
  48. }
  49. inline void dfs2(int x,int col)//第二遍dfs预处理
  50. {
  51. register int i;
  52. if(son[fac[dfn[x]=++d]=x]) dfs2(son[x],col);
  53. for(Top[x]=col,i=lnk[x];i;i=e[i].nxt)
  54. {
  55. if(!(fa[x]^e[i].to&&son[x]^e[i].to)) continue;
  56. dfs2(e[i].to,e[i].to);
  57. }
  58. }
  59. inline void Build(int l,int r,int rt)//建树
  60. {
  61. flag[rt]=-1;
  62. if(l^r)
  63. {
  64. register int mid=l+r>>1;
  65. if(l<=mid) Build(l,mid,rt<<1);
  66. if(r>mid) Build(mid+1,r,rt<<1|1);
  67. }
  68. }
  69. inline int Update(int l,int r,int rt,int ul,int ur,int x)//将[ul...ur]区间内所有软件包的安装状态修改为x(x=0表示未安装,x=1表示安装),并返回需要改变安装状态的软件包数
  70. {
  71. register int res=0;
  72. if(ul<=l&&r<=ur) {register int t;(x?(t=r-l+1,flag[rt]=1):(t=0,flag[rt]=0)),res=abs(t-Sum[rt]),Sum[rt]=t;return res;}
  73. register int mid=l+r>>1;
  74. PushDown(rt,mid-l+1,r-mid);
  75. if(ul<=mid) res=Update(l,mid,rt<<1,ul,ur,x);
  76. if(ur>mid) res+=Update(mid+1,r,rt<<1|1,ul,ur,x);
  77. PushUp(rt);
  78. return res;
  79. }
  80. public:
  81. inline void Init() {dfs1(1),dfs2(1,1),Build(1,n,1);}
  82. inline int uninstall(int pos) {return Update(1,n,1,dfn[pos],dfn[pos]+sz[pos]-1,0);}//卸载一个软件包,相当于修改以这个软件包为根节点的子树内所有软件包安装状态为0
  83. inline int install(int pos)//安装一个软件包,相当于修改这个软件包到根节点的所有软件包安装状态为1
  84. {
  85. register int res=0;
  86. while(Top[pos]>>1) res+=Update(1,n,1,dfn[Top[pos]],dfn[pos],1),pos=fa[Top[pos]];
  87. return res+Update(1,n,1,1,dfn[pos],1);
  88. }
  89. }S;
  90. int main()
  91. {
  92. register int i,Q,x;register char op;
  93. for(F.read(n),i=2;i<=n;++i) F.read(x),add(x+1,i);
  94. for(S.Init(),F.read(Q);Q;--Q)
  95. {
  96. F.read_char(op),F.read(x);
  97. if(op^'u') F.write(S.install(x+1)),F.write_char('\n');//对于安装操作
  98. else F.write(S.uninstall(x+1)),F.write_char('\n');//对于卸载操作
  99. }
  100. return F.end(),0;
  101. }

【BZOJ4196】[NOI2015] 软件包管理器(树链剖分)的更多相关文章

  1. [BZOJ4196][NOI2015]软件包管理器(树链剖分)

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

  2. BZOJ4196[Noi2015]软件包管理器——树链剖分+线段树

    题目描述 Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件源下载软件包,同时自动解决所有的依赖(即下载安装这个 ...

  3. bzoj4196 [Noi2015]软件包管理器——树链剖分

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4196 树链剖分. 代码如下: #include<iostream> #inclu ...

  4. [Bzoj4196] [NOI2015] 软件包管理器 [树链剖分,线段树]

    题解摘要:树链剖分后用线段树区间查询修改,对于安装软件,将改点到根的路径全部变为1,对于卸载软件,将子树清空.注意边界,编号是从0开始的,容易漏掉树根. 第一次写树剖- #include <io ...

  5. bzoj4196 [Noi2015]软件包管理器 树链剖分+线段树

    先把树剖分了(又是dfs1.dfs2),然后区间求和.区间覆盖即可 难得的1A好(shui)题 ——写了那么多题,终于有一道是1A的了,加上上一次连续交了几遍A的程序,我的状态莫名好看啊233 总结: ...

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. java部分基础知识整理----百度脑图版

    近期发现,通过百度脑图可以很好的归纳总结和整理知识点,本着学习和复习的目的,梳理了一下java部分的知识点,不定期更新,若有不恰之处,请指正,谢谢! 脑图链接如下:java部分基础知识整理----百度 ...

  2. Java 8 Optional类使用的实践经验

    前言 Java中空指针异常(NPE)一直是令开发者头疼的问题.Java 8引入了一个新的Optional类,使用该类可以尽可能地防止出现空指针异常. Optional 类是一个可以为null的容器对象 ...

  3. 算法学习分析-点分治 HDU 6269 Master of Subgraph

    首先给出定义 点分治是一种处理树上路径的工具 挂出一道题目来:Master of Subgraph 这道题目让你求所有联通子图加和所能产生数字,问你1到m之间,那些数字可以被产生 这道题目,假如我们利 ...

  4. lifecycle-mapping-metadata.xml

    <?xml version="1.0" encoding="UTF-8"?> <lifecycleMappingMetadata> &l ...

  5. servlet获取并存储web.xml中context-param参数

    在web.xml中定义了context-param,一般不会随意改动,所以在监听器中做一次处理,容器启动时读取并存储在Properties中,方便以后取值. SysProperties 类用于存储 c ...

  6. webfont应用系列(二)如何制作图标字体?

    工具: Adobe Illustrator CS5 Fontographer 5.1,下载地址 1.打开Fontographer,菜单"File"->"New&qu ...

  7. POJ 1061青蛙的约会。求解(x+mT)%L=(y+nT)%L的最小步数T。

    因为是同余,所以就是(x+mT)%L-(y+nT)%L=0.可以写成(x-y+(m-n)T)%L=0.就是这个数是L的倍数啦.那么我可以这样x-y+(m-n)T + Ls = 0.就可以了,s可正可负 ...

  8. (转)Linux网络接口配置文件ifcfg-eth0解析

    原文:http://blog.51cto.com/xtbao/1671739 https://www.cnblogs.com/arvintang/p/5990599.html http://blog. ...

  9. Maven的学习资料收集--(十)Myeclipse下创建Maven的Web项目

    先要在MyEclipse中对Maven进行设置: 到此Maven对MyEclipse的支持设置完毕.   下面我们在MyEclipse中创建一个Maven标准的Web工程: New --> We ...

  10. arcgis js 几种拓扑关系详解

    arcgis js的拓扑关系,在处理复杂逻辑和分析时,可以通过拓扑关系,减小客户端的工作量 拓扑关系: 1.overlaps 重叠 这里的重叠跟平时我们理解的不太一样,这里的重叠,必须是A与B有交集, ...