洛谷P2146&&DTOJ2409 [NOI2015]软件包管理器

  • 题目
    • 题目描述
    • 输入格式
    • 输出格式
    • 样例
      • 样例输入1
      • 样例输出1
      • 样例输入2
      • 样例输出2
    • 数据范围与提示
      • 样例1说明
      • 数据范围
  • 题解

题目

题目描述

Linux用户和OS X用户一定对软件包管理器不会陌生
通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件源下载软件包,同时自动解决所有的依赖(即下载安装这个软件包的安装所依赖的其它软件包),完成所有的配置
Debian/Ubuntu使用的apt-getFedora/CentOS使用的yum,以及OS X下可用的homebrew都是优秀的软件包管理器
你决定设计你自己的软件包管理器
不可避免地,你要解决软件包之间的依赖问题
如果软件包A依赖软件包B,那么安装软件包A以前,必须先安装软件包B
同时,如果想要卸载软件包B,则必须卸载软件包A
现在你已经获得了所有的软件包之间的依赖关系,而且,由于你之前的工作,除0号软件包以外,在你的管理器当中的软件包都会依赖一个且仅一个软件包,而0号软件包不依赖任何一个软件包
依赖关系不存在环(若有m(m⩾2)m(m\geqslant 2)m(m⩾2)个软件包A1,A2,A3,⋯⋯,AmA_1,A_2,A_3,\cdots \cdots,A_mA1​,A2​,A3​,⋯⋯,Am​,其中A1A_1A1​依赖A2A_2A2​,A2A_2A2​依赖A3A_3A3​,A3A_3A3​依赖A4A_4A4​,……,Am−1A_{m−1}Am−1​依赖AmA_mAm​,而AmA_mAm​依赖A1A_1A1​,则称这mmm个软件包的依赖关系构成环),当然也不会有一个软件包依赖自己
现在你要为你的软件包管理器写一个依赖解决程序
根据反馈,用户希望在安装和卸载某个软件包时,快速地知道这个操作实际上会改变多少个软件包的安装状态(即安装操作会安装多少个未安装的软件包,或卸载操作会卸载多少个已安装的软件包),你的任务就是实现这个部分
注意,安装一个已安装的软件包,或卸载一个未安装的软件包,都不会改变任何软件包的安装状态,即在此情况下,改变安装状态的软件包数为000

输入格式

输入文件的第111行包含111个正整数nnn,表示软件包的总数,软件包从000开始编号
随后一行包含n−1n−1n−1个整数,相邻整数之间用单个空格隔开,分别表示1,2,3,⋯⋯,n−2,n−11,2,3,\cdots \cdots,n−2,n−11,2,3,⋯⋯,n−2,n−1号软件包依赖的软件包的编号
接下来一行包含111个正整数qqq,表示询问的总数
之后qqq行,每行111个询问
询问分为两种:
install x:表示安装软件包xxx
uninstall x:表示卸载软件包xxx
你需要维护每个软件包的安装状态,一开始所有的软件包都处于未安装状态
对于每个操作,你需要输出这步操作会改变多少个软件包的安装状态,随后应用这个操作(即改变你维护的安装状态)

输出格式

输出文件包括qqq行
输出文件的第iii行输出111个整数,为第iii步操作中改变安装状态的软件包数

样例

样例输入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说明


一开始所有的软件包都处于未安装状态
安装555号软件包,需要安装0,1,50,1,50,1,5三个软件包
之后安装666号软件包,只需要安装666号软件包
此时安装了0,1,5,60,1,5,60,1,5,6四个软件包
卸载 1 号软件包需要卸载1,5,61,5,61,5,6三个软件包
此时只有000号软件包还处于安装状态
之后安装444号软件包,需要安装1,41,41,4两个软件包
此时0,1,40,1,40,1,4处在安装状态
最后,卸载000号软件包会卸载所有的软件包

数据范围

题解

树剖裸题……
建线段树记录相应一段DFS序中安装软件的数量
安装软件的时候就直接把这个软件到根节点的路径上的所有点的权值全部修改为111
卸载软件的时候就直接把这个软件的所有子树上的所有点的权值全部修改为000就可以了
剩下的细节我就不说了,反正是个很裸的题
附上代码:

#include<cstdio>
#define l(x) t[x].l
#define r(x) t[x].r
#define s(x) t[x].sum
#define a(x) t[x].add
int n,q,tot,cnt,head[100010],to[100010],nxt[100010],fa[100010],size[100010],dep[100010],big[100010];
int top[100010],dfn[100010],dfn2[100010],sor[100010];
char op[20];
struct ppap
{int l,r,sum,add;
}t[400010];
void add(int u,int v)
{nxt[++tot]=head[u],head[u]=tot,to[tot]=v;
}
void dfs1(int x,int deep)
{dep[x]=deep,size[x]=1;for(int i=head[x];i;i=nxt[i]){dfs1(to[i],deep+1),size[x]+=size[to[i]];if(size[to[i]]>size[big[x]]) big[x]=to[i];}
}
void dfs2(int x,int Top)
{top[x]=Top,dfn[x]=++cnt,sor[cnt]=x;if(big[x]==100001){dfn2[x]=cnt;return;}dfs2(big[x],Top);for(int i=head[x];i;i=nxt[i]) if(to[i]!=big[x]) dfs2(to[i],to[i]);dfn2[x]=cnt;
}
void spread(int p)
{if(a(p)){a(p*2)=a(p*2+1)=a(p);if(a(p)==1) s(p*2)=r(p*2)-l(p*2)+1,s(p*2+1)=r(p*2+1)-l(p*2+1)+1;if(a(p)==2) s(p*2)=s(p*2+1)=0;a(p)=0;}
}
void build(int p,int l,int r)
{l(p)=l,r(p)=r;if(l==r) return;int mid=(l+r)>>1;build(p*2,l,mid);build(p*2+1,mid+1,r);
}
int ask(int p,int l,int r)
{if(l<=l(p)&&r>=r(p)) return s(p);spread(p);int mid=(l(p)+r(p))>>1,ans=0;if(l<=mid) ans+=ask(p*2,l,r);if(r>mid) ans+=ask(p*2+1,l,r);return ans;
}
void change(int p,int l,int r,int x)
{if(l<=l(p)&&r>=r(p)){if(x) a(p)=1,s(p)=r(p)-l(p)+1;else a(p)=2,s(p)=0;return;}spread(p);int mid=(l(p)+r(p))>>1;if(l<=mid) change(p*2,l,r,x);if(r>mid) change(p*2+1,l,r,x);s(p)=s(p*2)+s(p*2+1);
}
int Install(int x)
{int ans=dep[x],u=x;while(top[u]) ans-=ask(1,dfn[top[u]],dfn[u]),change(1,dfn[top[u]],dfn[u],1),u=fa[top[u]];ans-=ask(1,dfn[0],dfn[u]),change(1,dfn[0],dfn[u],1);return ans;
}
int Uninstall(int x)
{int ans;ans=ask(1,dfn[x],dfn2[x]),change(1,dfn[x],dfn2[x],0);return ans;
}
int main()
{freopen("manager.in","r",stdin);freopen("manager.out","w",stdout);scanf("%d",&n),big[0]=100001;for(int i=1,x;i<n;i++) scanf("%d",&x),add(x,i),fa[i]=x,big[i]=100001;dfs1(0,1),dfs2(0,0),build(1,1,n);scanf("%d",&q);for(int i=1,x;i<=q;i++){scanf("%s %d",op,&x);if(op[0]=='i') printf("%d\n",Install(x));else printf("%d\n",Uninstall(x));}
}

洛谷P2146DTOJ2409 [NOI2015]软件包管理器相关推荐

  1. [NOI2015]软件包管理器

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

  2. P2146 [NOI2015] 软件包管理器

    P2146 [NOI2015] 软件包管理器 题意: 如果软件包 a 依赖软件包 b,那么安装软件包 a 以前,必须先安装软件包 b.同时,如果想要卸载软件包 b,则必须卸载软件包 a. 软件包之间存 ...

  3. BZOJ4196:[NOI2015]软件包管理器——题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=4196 https://www.luogu.org/problemnew/show/P2146 你决定 ...

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

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

  5. bzoj4196:[Noi2015]软件包管理器

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

  6. BZOJ4196: [Noi2015]软件包管理器 (好题

    好题啊,做到这题想起以前靠线段树维护子树的时候 那时候没见过链操作,搞不清树剖有什么用 这题就结合了子树操作和树链操作,也是把dfs序的in out完整用上了 树剖exp++ #include< ...

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

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

  8. NOI2015 Day1 T2 软件包管理器 树链剖分

    NKOJ3423 NOI2015 软件包管理器 时间限制 : 20000 MS 空间限制 : 524288 KB 问题描述 Linux用户和OS X用户一定对软件包管理器不会陌生.通过软件包管理器,你 ...

  9. 【NOI2015】软件包管理器

    NOI难得的水题,话说还是T2诶--又学到了线段树的一种新的魔性使用 看sxysxy大神的代码才写出来的,sxysxy_orz 原题: Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包 ...

最新文章

  1. 【C++】C++11 STL算法(四):二分查找法(Binary search operations)、合并操作
  2. MySQL中的blob和clob
  3. 【Android 应用开发】Android 开发错误集锦
  4. C#字符串截取学习总结
  5. 图像变清晰 图像放大 提高分辨率 提高清晰度
  6. Oracle通过OCI批量加载需要注意的问题
  7. demo4 debug - create class instance - component works as type
  8. Gvim 字体大小设置和FencView插件安装
  9. SICP~计算机程序的构造和解释~ 1.12 c++实现
  10. Spring Boot中使用log4j实现http请求日志入mongodb
  11. python批量生成图_利用Python批量生成任意尺寸的图片
  12. 【Elasticsearch】关于 Analyzers 的一切,第一部分
  13. 第三方服务-极光推送
  14. 30.github 搭建 blog
  15. 用VScode写html文件以及调用浏览器运行
  16. EASE-Grid投影
  17. 整理任正非思想:要树立服务意识、品牌意识、群体意识-1996
  18. 深度学习面试问题总结
  19. 【译】Steve Yegge的文章《Practicing Programming》
  20. 按钮点击后的颜色css,CSS实现按钮点击后根据背景色加深效果-一颗优雅草bigniu...

热门文章

  1. ROS订阅激光点云数据并画直线
  2. mq多个消费者消费一个消息_限塑“动真格”,他们免费给消费者发了5000多个无纺布购物袋...
  3. WIN32_API函数大全
  4. 模拟集成电路应用之Burn in
  5. [译] 第三章 MCMC
  6. 那些醍醐灌顶的句子,你细品~细思极恐~
  7. 聚焦 DPU 技术研发与创新 天翼云打造全新一代云计算体系结构
  8. Win11之g++和build-essential的美妙甜甜圈
  9. HBuilder打包H5成mp-weixin文件到微信开发者工具运行
  10. CTF-攻防世界-MISC-高手进阶区(001-018 持续更新中...)