【BZOJ4196】【NOI2015】软件包管理器

题面

题目描述

Linux用户和OSX用户一定对软件包管理器不会陌生。通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件源下载软件包,同时自动解决所有的依赖(即下载安装这个软件包的安装所依赖的其它软件包),完成所有的配置。ebian/Ubuntu使用的apt-get,Fedora/CentOS使用的yum,以及OSX下可用的homebrew都是优秀的软件包管理器。

你决定设计你自己的软件包管理器。不可避免地,你要解决软件包之间的依赖问题。如果软件包A依赖软件包B,那么安装软件包A以前,必须先安装软件包B。同时,如果想要卸载软件包B,则必须卸载软件包A。现在你已经获得了所有的软件包之间的依赖关系。而且,由于你之前的工作,除0号软件包以外,在你的管理器当中的软件包都会依赖一个且仅一个软件包,而0号软件包不依赖任何一个软件包。依赖关系不存在环(若有m(m≥2)个软件包A1,A2,A3,⋯,Am,其中A1依赖A2,A2依赖A3,A3依赖A4,……,A[m-1]依赖Am,而Am依赖A1,则称这m个软件包的依赖关系构成环),当然也不会有一个软件包依赖自己。

现在你要为你的软件包管理器写一个依赖解决程序。根据反馈,用户希望在安装和卸载某个软件包时,快速地知道这个操作实际上会改变多少个软件包的安装状态(即安装操作会安装多少个未安装的软件包,或卸载操作会卸载多少个已安装的软件包),你的任务就是实现这个部分。注意,安装一个已安装的软件包,或卸载一个未安装的软件包,都不会改变任何软件包的安装状态,即在此情况下,改变安装状态的软件包数为0。

输入输出格式

输入格式:

从文件manager.in中读入数据。

输入文件的第1行包含1个整数n,表示软件包的总数。软件包从0开始编号。

随后一行包含n−1个整数,相邻整数之间用单个空格隔开,分别表示1,2,3,⋯,n−2,n−1号软件包依赖的软件包的编号。

接下来一行包含1个整数q,表示询问的总数。之后q行,每行1个询问。询问分为两种:

install x:表示安装软件包x

uninstall x:表示卸载软件包x

你需要维护每个软件包的安装状态,一开始所有的软件包都处于未安装状态。

对于每个操作,你需要输出这步操作会改变多少个软件包的安装状态,随后应用这个操作(即改变你维护的安装状态)。

输出格式:

输出到文件manager.out中。

输出文件包括q行。

输出文件的第i行输出1个整数,为第i步操作中改变安装状态的软件包数。

输入输出样例

输入样例#1:

7

0 0 0 1 1 5

5

install 5

install 6

uninstall 1

install 4

uninstall 0

输出样例#1:

3

1

3

2

3

输入样例#2:

10

0 1 2 1 3 0 0 3 2

10

install 0

install 3

uninstall 2

install 7

install 5

install 9

uninstall 9

install 4

install 1

install 9

输出样例#2:

1

3

2

1

3

1

1

1

0

1

题解

树链剖分良心板子题

搞完之后直接线段树暴力搞就可以了

真心良心题....

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cstdlib>
  4. #include<cstring>
  5. #include<cmath>
  6. #include<algorithm>
  7. #include<set>
  8. #include<map>
  9. #include<vector>
  10. using namespace std;
  11. #define MAX 101000
  12. #define lson (now<<1)
  13. #define rson (now<<1|1)
  14. inline int read()
  15. {
  16. int x=0,t=1;char ch=getchar();
  17. while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
  18. if(ch=='-')t=-1,ch=getchar();
  19. while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
  20. return x*t;
  21. }
  22. struct Line
  23. {
  24. int v,next;
  25. }e[MAX];
  26. int h[MAX],cnt=1,n,ff[MAX],dep[MAX],top[MAX],size[MAX],hson[MAX];
  27. int dfn[MAX],low[MAX],tim;
  28. inline void Add(int u,int v)
  29. {
  30. e[cnt]=(Line){v,h[u]};
  31. h[u]=cnt++;
  32. }
  33. void dfs1(int u)
  34. {
  35. size[u]=1;dep[u]=dep[ff[u]]+1;
  36. for(int i=h[u];i;i=e[i].next)
  37. {
  38. int v=e[i].v;
  39. dfs1(v);
  40. if(size[v]>size[hson[u]])hson[u]=v;
  41. size[u]+=size[v];
  42. }
  43. }
  44. void dfs2(int u,int tp)
  45. {
  46. dfn[u]=++tim;
  47. top[u]=tp;
  48. if(hson[u])dfs2(hson[u],tp);
  49. for(int i=h[u];i;i=e[i].next)
  50. {
  51. int v=e[i].v;
  52. if(v==hson[u])continue;
  53. dfs2(v,v);
  54. }
  55. low[u]=tim;
  56. }
  57. struct Node
  58. {
  59. int s,ly;
  60. }t[MAX<<2];
  61. int L,R,K;
  62. void pushup(int now){t[now].s=t[lson].s+t[rson].s;}
  63. void pushdown(int now,int l,int r)
  64. {
  65. if(!t[now].ly)return;
  66. if(t[now].ly==1)
  67. {
  68. int mid=(l+r)>>1;
  69. t[lson].s=mid-l+1;
  70. t[rson].s=r-mid;
  71. t[lson].ly=t[rson].ly=1;
  72. }
  73. else
  74. {
  75. t[lson].s=t[rson].s=0;
  76. t[lson].ly=t[rson].ly=2;
  77. }
  78. t[now].ly=0;
  79. }
  80. void putlazy(int now,int l,int r,int k)
  81. {
  82. if(k==1)
  83. {
  84. t[now].s=(r-l+1);
  85. t[now].ly=1;
  86. }
  87. else
  88. {
  89. t[now].s=0;
  90. t[now].ly=2;
  91. }
  92. }
  93. int Query(int now,int l,int r)
  94. {
  95. if(l>=L&&r<=R)return t[now].s;
  96. pushdown(now,l,r);
  97. int mid=(l+r)>>1,re=0;
  98. if(mid>=L)re+=Query(lson,l,mid);
  99. if(mid<R)re+=Query(rson,mid+1,r);
  100. pushup(now);
  101. return re;
  102. }
  103. void Modify(int now,int l,int r)
  104. {
  105. if(l>=L&&r<=R)
  106. {
  107. putlazy(now,l,r,K);
  108. return;
  109. }
  110. int mid=(l+r)>>1;
  111. if(mid>=L)Modify(lson,l,mid);
  112. if(mid<R)Modify(rson,mid+1,r);
  113. pushup(now);
  114. }
  115. int Answer(int u)
  116. {
  117. K=1;int re=0;
  118. while(u)
  119. {
  120. L=dfn[top[u]];R=dfn[u];
  121. re-=Query(1,1,n);
  122. Modify(1,1,n);
  123. re+=Query(1,1,n);
  124. u=ff[top[u]];
  125. }
  126. return re;
  127. }
  128. int main()
  129. {
  130. n=read();
  131. for(int i=2;i<=n;++i)
  132. Add(ff[i]=read()+1,i);
  133. dfs1(1);dfs2(1,1);
  134. int q=read();
  135. char ch[15];
  136. while(q--)
  137. {
  138. scanf("%s",ch);int x=read()+1;
  139. if(ch[0]=='i')
  140. printf("%d\n",Answer(x));
  141. else
  142. {
  143. L=dfn[x];R=low[x];K=2;
  144. printf("%d\n",Query(1,1,n));
  145. Modify(1,1,n);
  146. }
  147. }
  148. }

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

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

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

  2. [UOJ#128][BZOJ4196][Noi2015]软件包管理器

    [UOJ#128][BZOJ4196][Noi2015]软件包管理器 试题描述 Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管 ...

  3. 【BZOJ-2325】道馆之战 树链剖分 + 线段树

    2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 1153  Solved: 421[Submit][Statu ...

  4. 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树

    [BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...

  5. BZOJ2243 (树链剖分+线段树)

    Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...

  6. POJ3237 (树链剖分+线段树)

    Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...

  7. bzoj4034 (树链剖分+线段树)

    Problem T2 (bzoj4034 HAOI2015) 题目大意 给定一颗树,1为根节点,要求支持三种操作. 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子 ...

  8. HDU4897 (树链剖分+线段树)

    Problem Little Devil I (HDU4897) 题目大意 给定一棵树,每条边的颜色为黑或白,起始时均为白. 支持3种操作: 操作1:将a->b的路径中的所有边的颜色翻转. 操作 ...

  9. Aizu 2450 Do use segment tree 树链剖分+线段树

    Do use segment tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.bnuoj.com/v3/problem_show ...

  10. 【POJ3237】Tree(树链剖分+线段树)

    Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edg ...

随机推荐

  1. PLEC-交流电机系统+笔记

    1.固有机械特性近似图 2.三相交流电机的控制系统 1)理论推导 第一次制动选择能耗制动,第二次制动选择倒拉制动. 2)模型搭建 3)模拟仿真 3.心得体会和笔记总结 制动方式的选择主要是根据各个制动 ...

  2. 常用VI操作命令

    # ------------------- VI basic ------------------------------- # file name: VI_basic # author : # da ...

  3. zabbix 3.4.1 解决中文乱码

    docker zabbix中文乱码 基础镜像为:zabbix/zabbix-web-nginx-mysql 1.首先下载msyh.ttf 2.docker cp msyh.ttf 容器:/usr/sh ...

  4. 洛谷P1345 [USACO5.4]奶牛的电信Telecowmunication【最小割】分析+题解代码

    洛谷P1345 [USACO5.4]奶牛的电信Telecowmunication[最小割]分析+题解代码 题目描述 农夫约翰的奶牛们喜欢通过电邮保持联系,于是她们建立了一个奶牛电脑网络,以便互相交流. ...

  5. CENTOS6.6上搭建单实例ORACLE12C

    本文来自我的github pages博客http://galengao.github.io/ 即www.gaohuirong.cn 摘要: 自己在centos6.6上搭建的单实例oracle12c 由 ...

  6. web基础知识通信概述URI与http

    1.url是什么,有什么作用: 说白了就是我们常说的网址:正规来说就是统一资源定位符是对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,是互联网上标准资源的地址. 互联网上的每个文件都有一个 ...

  7. hdu3480 Division(dp平行四边形优化)

    题意:将n个数分成m段,每段的代价为最大值减最小值的平方,为代价最小是多少n<=10000 ,m<=5000 题解:先拍好序,从小到大,这样绝对是花费最小的,不过怎么样来做呢?一定很容易想 ...

  8. 在Mac下配置Maven环境

    下载Maven安装文件,(http://maven.apache.org/download.html)如:apache-maven-3.5.0-bin.zip,然后解压到本地目录. 打开 .bash_ ...

  9. C++学习,两个小的语法错误-network-programming

    1.bool CServerSocket::initSocket(const char* ip=NULL,const UINT &port)://会出现默认参数为2的错误 解决方案: //C+ ...

  10. hdu 2047递推

    A[N]表示以E或者F结尾的情况下的方案数,B[N]表示以O结尾的情况下的方案数,F[N]=3*A[N-1]+2*B[N-1] 同时,A[N]=2*B[N-1]+2*A[N-1],B[N-1]=A[N ...