noi2015软件包管理器

2023-11-02 04:32
文章标签 管理器 软件包 noi2015

本文主要是介绍noi2015软件包管理器,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

【题目描述】

你决定设计你自己的软件包管理器。不可避免的,你要解决软件包之间的依赖关系。如果A依赖B,那么安装A之前需安装B,卸载B之前须卸载A。0号软件包不依赖任何软件包。依赖关系不存在环(包括自环)。

你的任务是,求出每次安装、删除操作会改变多少个包的状态。

安装一个已安装的软件包,或者卸载一个未安装的软件包,都不会改变任何软件包的安装状态,即在此情况下,改变安装状态的软件包数为0

每次操作不仅需要计算安装软件包数,还作为操作影响后来的安装/删除

【输入格式】

第一行一个整数n,表示软件包的总数。

随后n-1个整数 a1,a2,...an1 ,表示第i个软件包依赖第 ai 个软件包

接下来一行一个整数q,表示询问数

之后q行,每行一个询问,询问分为两种

install xx

uninstall xx

【输出格式】

q行,每行一个整数,为第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

【样例说明1】:

一开始所有的软件包都处于未安装状态。

安装5号软件包,需安装0,1,5三个软件包

之后安装6号软件包,只需安装6号软件包。此时安装了0,1,5,6四个软件包。

卸载1号软件包需要卸载1,5,6三个软件包,此时只有0号软件包还处于安装状态

之后安装4号软件包,需安装1,4两个软件包。此时0,1,4处于安装状态

最后,卸载0号软件包会卸载所有的软件包

【样例输入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,2:n=5000 q=5000

3,4:n=100000 q=100000 没有卸载操作

5,6,7,8 n=100000,q=100000 依赖关系和操作随机

9-20 n=100000,q=100000 不随机

【来源】

NOI2015Day1T2

对于题面的描述的,我们很容易想到它是棵树,并且节点又是1e+5,我们选择用树剖+线段树;

我们维护线段树上每一个点的状态(安装或未安装,安装用1来表示,未安装用-1来表示)和当前节点已被覆盖的点数,未被覆盖的点数可以也维护,也可以用区间长减去已被覆盖节点数,当一个线段树节点被打上安装或未安装标记时,就将答案加上已被覆盖的点数或未被覆盖点数并更新其值(一个为0,另一个为区间长),在拿它来更新父亲节点

所维护的信息,最后输出答案就行。。

代码如下:

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <string>
  5. #include <algorithm>
  6. using namespace std;
  7. const int MAX=100000+10;
  8. int fa[MAX];
  9. int dep[MAX];
  10. int son[MAX]={0};
  11. int top[MAX];
  12. int size[MAX];
  13. int tid[MAX];
  14. int head[MAX]={0};
  15. int to[MAX<<1];
  16. int next[MAX<<1]={0};
  17. int edge=1,tim=0;
  18. int n;
  19. inline void dfs1(int x,int p,int d){
  20. fa[x]=p;
  21. dep[x]=d;
  22. size[x]=1;
  23. for(int i=head[x];i;i=next[i]){
  24. int u=to[i];
  25. if(u!=p){
  26. dfs1(u,x,d+1);
  27. size[x]+=size[u];
  28. if(size[u]>size[son[x]]||!son[x])
  29. son[x]=u;
  30. }
  31. }
  32. }
  33. inline void dfs2(int x,int p){
  34. tid[x]=++tim;
  35. top[x]=p;
  36. if(!son[x])
  37. return ;
  38. dfs2(son[x],p);
  39. for(int i=head[x];i;i=next[i]){
  40. int u=to[i];
  41. if(u!=fa[x]&&u!=son[x])
  42. dfs2(u,u);
  43. }
  44. }
  45. #define isnum (c>='0'&&c<='9')
  46. inline void read(int& x){
  47. x=0;
  48. char c=getchar();
  49. while(!isnum)
  50. c=getchar();
  51. while(isnum){
  52. x=(x<<3)+(x<<1)+c-'0';
  53. c=getchar();
  54. }
  55. }
  56. inline void addedge(int x,int y){
  57. to[edge]=y,next[edge]=head[x],head[x]=edge++;
  58. to[edge]=x,next[edge]=head[y],head[y]=edge++;
  59. }
  60. int isum[MAX<<2]={0},usum[MAX<<2];
  61. int ins[MAX<<2]={0};
  62. int ans;
  63. int l,r;
  64. #define lson o<<1,L,mid
  65. #define rson o<<1|1,mid+1,R
  66. inline void pushup(int o){
  67. isum[o]=isum[o<<1]+isum[o<<1|1];
  68. usum[o]=usum[o<<1]+usum[o<<1|1];
  69. }
  70. inline void pushdown(int o,int L,int R){
  71. int mid=(L+R)>>1;
  72. if(ins[o]==1){
  73. isum[o<<1]=(mid-L+1);
  74. usum[o<<1]=0;
  75. isum[o<<1|1]=R-mid;
  76. usum[o<<1|1]=0;
  77. ins[o<<1]=ins[o];
  78. ins[o<<1|1]=ins[o];
  79. ins[o]=0;
  80. }
  81. else {
  82. isum[o<<1]=0;
  83. usum[o<<1]=mid-L+1;
  84. isum[o<<1|1]=0;
  85. usum[o<<1|1]=R-mid;
  86. ins[o<<1]=ins[o];
  87. ins[o<<1|1]=ins[o];
  88. ins[o]=0;
  89. }
  90. }
  91. inline void build(int o,int L,int R){
  92. usum[o]=(R-L+1);
  93. if(L==R){
  94. return ;
  95. }
  96. int mid=(L+R)>>1;
  97. build(lson);
  98. build(rson);
  99. pushup(o);
  100. }
  101. inline void query1(int o,int L,int R){
  102. if(L>=l&&R<=r){
  103. ins[o]=1;
  104. ans+=usum[o];
  105. usum[o]=0;
  106. isum[o]=(R-L+1);
  107. return ;
  108. }
  109. else if(L!=R){
  110. int mid=(L+R)>>1;
  111. if(ins[o]!=0)
  112. pushdown(o,L,R);
  113. if(mid>=l)
  114. query1(lson);
  115. if(mid<r)
  116. query1(rson);
  117. pushup(o);
  118. }
  119. }
  120. inline void query2(int o,int L,int R){
  121. if(L>=l&&R<=r){
  122. ins[o]=-1;
  123. ans+=isum[o];
  124. isum[o]=0;
  125. usum[o]=(R-L+1);
  126. return ;
  127. }
  128. else if(L!=R){
  129. if(ins[o]!=0)
  130. pushdown(o,L,R);
  131. int mid=(L+R)>>1;
  132. if(mid>=l)
  133. query2(lson);
  134. if(mid<r)
  135. query2(rson);
  136. pushup(o);
  137. }
  138. }
  139. inline void Query1(int x,int y){
  140. ans=0;
  141. while(top[x]!=top[y]){
  142. if(dep[top[x]]<dep[top[y]])
  143. swap(x,y);
  144. l=tid[top[x]];
  145. r=tid[x];
  146. query1(1,1,n);
  147. x=fa[top[x]];
  148. }
  149. if(dep[x]>dep[y])
  150. swap(x,y);
  151. l=tid[x],r=tid[y];
  152. query1(1,1,n);
  153. }
  154. inline void Query2(int x){
  155. ans=0;
  156. l=tid[x],r=tid[x]+size[x]-1;
  157. query2(1,1,n);
  158. }
  159. int main(){
  160. freopen("manager.in","r",stdin);
  161. freopen("manager.out","w",stdout);
  162. read(n);
  163. int x;
  164. for(int i=2;i<=n;i++){
  165. read(x);
  166. addedge(i,x+1);
  167. }
  168. int m;
  169. read(m);
  170. dfs1(1,1,1);
  171. dfs2(1,1);
  172. build(1,1,n);
  173. string s;
  174. for(int i=1;i<=m;i++){
  175. cin>>s;
  176. read(x);
  177. if(s[0]=='i'){
  178. Query1(1,x+1);
  179. printf("%d\n",ans);
  180. }
  181. else {
  182. Query2(x+1);
  183. printf("%d\n",ans);
  184. }
  185. }
  186. return 0;
  187. }

这篇关于noi2015软件包管理器的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/328139

相关文章

【Python知识宝库】上下文管理器与with语句:资源管理的优雅方式

🎬 鸽芷咕:个人主页  🔥 个人专栏: 《C++干货基地》《粉丝福利》 ⛺️生活的理想,就是为了理想的生活! 文章目录 前言一、什么是上下文管理器?二、上下文管理器的实现三、使用内置上下文管理器四、使用`contextlib`模块五、总结 前言 在Python编程中,资源管理是一个重要的主题,尤其是在处理文件、网络连接和数据库

Apache Tiles 布局管理器

陈科肇 =========== 1.简介 一个免费的开源模板框架现代Java应用程序。  基于该复合图案它是建立以简化的用户界面的开发。 对于复杂的网站,它仍然最简单,最优雅的方式来一起工作的任何MVC技术。 Tiles允许作者定义页面片段可被组装成在运行一个完整的网页。  这些片段,或Tiles,可以用于为了降低公共页面元素的重复,简单地包括或嵌入在其它瓦片,制定了一系列可重复使用

Qt-常用控件(3)-多元素控件、容器类控件和布局管理器

1. 多元素控件 Qt 中提供的多元素控件有: QListWidgetQListViewQTableWidgetQTableViewQTreeWidgetQTreeView xxWidget 和 xxView 之间的区别,以 QTableWidget 和 QTableView 为例. QTableView 是基于 MVC 设计的控件.QTableView 自身不持有数据,使用 QTab

Android SmsManager(短信管理器),发送短信息

AndroidManifest.xml <uses-permission android:name="android.permission.SEND_SMS"/> <?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns

Android 电话管理器TelephonyManager,获取网络,SIM卡信息

// 获取系统TelephonyManager对象 TelephonyManager telephonyManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE); AndroidManifest.xml package shortcut.song.com.myapplication;import an

828华为云征文|部署电影收藏管理器 Radarr

828华为云征文|部署电影收藏管理器 Radarr 一、Flexus云服务器X实例介绍1.1 云服务器介绍1.2 应用场景1.3 性能模式 二、Flexus云服务器X实例配置2.1 重置密码2.2 服务器连接2.3 安全组配置 三、部署 Radarr3.1 Radarr 介绍3.2 Docker 环境搭建3.3 Radarr 部署3.4 Radarr 使用 四、总结 一、Flexu

随手记(2)-java.sql.SQLException: [Microsoft][ODBC 驱动程序管理器] 未发现数据源名称并且未指定默认驱动程序

问题描述: 在使用Java连接access数据的.mdb文件时候程序报如下错误 java.sql.SQLException: [Microsoft][ODBC 驱动程序管理器] 未发现数据源名称并且未指定默认驱动程序     错误原因: 在win7 office2013下报错 解决方法:  查看Java桥连程序连接字符串是否写成{Microsoft Access Driver (*.m

新型PyPI攻击技术可能导致超2.2万软件包被劫持

一种针对 Python 软件包索引(PyPI)注册表的新型供应链攻击技术已在野外被利用,并且目前正试图渗透到下游组织中。 软件供应链安全公司 JFrog 将其代号定为Revival Hijack,并称这种攻击方法可用于劫持 2.2万个现有 PyPI 软件包,并导致数十万次恶意软件包下载。这些易受攻击的软件包下载量已超过 10 万次,或已活跃超过 6 个月。 JFrog安全研究人员And

[Python]之with与上下文管理器

-python基础知识回顾 with 与上下文管理器 1.1文本操作回顾 # 1、以写的方式打开文件f = open("1.txt", "w")# 2、写入文件内容f.write("hello world")# 3、关闭文件f.close() 文件使用完后必须关闭 因文件对象会占用操作系统的资源,并且操作系统同一时间能打开的文件数量也是有限的 1.2存在的安全隐患: ① 由于文件

Qt中处理布局管理器之间的距离

一般的要让控件容器和子控件没有空隙, 有两种情况: (确保控件容器的margins设置成0)1. 子控件大小固定, 则控件容器大小也得固定, 确保没有空隙产生;2. 子控件大小动态变化, 则将其大小变化设置成扩展(expanding), 随控件容器变化; 那么,为了确保frame与内部控件一样高,我设置其最大高度:titleFrame->setMaximumHeight(16);同时却出现了