【NOI2015】软件包管理器
NOI难得的水题,话说还是T2诶……又学到了线段树的一种新的魔性使用
看sxysxy大神的代码才写出来的,sxysxy_orz
原题:
Linux用户和OSX用户一定对软件包管理器不会陌生。通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件源下载软件包,同时自动解决所有的依赖(即下载安装这个软件包的安装所依赖的其它软件包),完成所有的配置。Debian/Ubuntu使用的apt-get,Fedora/CentOS使用的yum,以及OSX下可用的homebrew都是优秀的软件包管理器。
主要就是两种树上线段树,树剖和dfs序列化,很裸,不过这里有一种线段树的魔性使用:(2017.12.5 upd:其实这就是个常规的赋值应用,我当年真是naive23333
给线段树修改的时候,delta不是+=z,而是=z,这个表示吧一个区间里面所有的数都变成z,一般用区间里面的数为1或0来表示有没有
然后在计算value(这里表示一个区间里面有几个)的时候应该是tree[x].delta*(tree[x].sright-tree[x].sleft+1);表示这一段区间里的东西要么有(delta=1),要么没有(delta=0),乘上长度就是有的个数
添加的时候先查一下这个点上面有几个,然后buff一下,用buff的长度减去之前查找的个数,就是需要再添加的个数
然后就是两种树上线段树结合一下很开心的水过了,因为树链的一端只能是根节点,所以在爬链的时候比原版本还要简单
不过写的时候犯了一个非常傻逼的错误,调了几十分钟
x=father[top[x]]写成x=father[x],整整多了几条链的复杂度qaqqqqqqqqqqqqqqqq
还以为是卡常问题,找了好长时间……
说一下几点需要注意的地方:
0是有意义的,所以如果没有重儿子要设成-1
同样因为标号从0开始,所以总共有7个点,但是标号只到6,dfs序的计数器初始化要设成-1(从0开始)
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
int read(){int z=,mark=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-')mark=-; ch=getchar();}
while(ch>=''&&ch<=''){z=(z<<)+(z<<)+ch-''; ch=getchar();}
return z*mark;
}
struct ddd{int next,y;}e[];int LINK[],ltop=;
inline void insert(int x,int y){e[++ltop].next=LINK[x];LINK[x]=ltop;e[ltop].y=y;}
int n,m;
int size[],deep[],father[],big_child[],top[],n_value[];
int dfs_xv[],fan_xv[],er_xv[],xv_cnt=-;//注意因为从0开始,所以总共有7个点,但是编号只到6
void dfs1(int x,int _father,int _deep){
father[x]=_father,deep[x]=_deep,size[x]=;
int max_size=,max_child=-;//注意0有意义
for(int i=LINK[x];i;i=e[i].next)if(e[i].y!=father[x]){
dfs1(e[i].y,x,_deep+);
size[x]+=size[e[i].y];
if(size[e[i].y]>max_size) max_size=size[e[i].y],max_child=e[i].y;
}
big_child[x]=max_child;
}
void dfs2(int x,int _top){
top[x]=_top; dfs_xv[++xv_cnt]=x; fan_xv[x]=xv_cnt;
if(big_child[x]!=-) dfs2(big_child[x],_top);//注意-1
for(int i=LINK[x];i;i=e[i].next)if(e[i].y!=father[x] && e[i].y!=big_child[x])
dfs2(e[i].y,e[i].y);
er_xv[x]=xv_cnt;
}
struct dcd{int sleft,sright,mid,svalue,delta;}tree[];
void stev(int x){ tree[x].svalue=tree[x].delta*(tree[x].sright-tree[x].sleft+);}//sxysxy_orz
void get_SegmentTree(int x,int _left,int _right){
tree[x].sleft=_left,tree[x].sright=_right,tree[x].mid=(_left+_right)>>;
tree[x].svalue=tree[x].delta=;
if(_left!=_right) get_SegmentTree(x<<,_left,tree[x].mid),get_SegmentTree(x<<|,tree[x].mid+,_right);
}
int search(int x,int _left,int _right){
if(tree[x].sleft==_left && tree[x].sright==_right) return tree[x].svalue;
else{
if(tree[x].delta!=-){
tree[x<<].delta=tree[x<<|].delta=tree[x].delta; tree[x].delta=-;//注意这里并不是加上,而是设置为,注意-1 (sxysxy_orz
stev(x<<),stev(x<<|);
tree[x].delta=-;
}
if(_left<=tree[x].mid && _right>tree[x].mid) return search(x<<,_left,tree[x].mid)+search(x<<|,tree[x].mid+,_right);
else if(_right<=tree[x].mid) return search(x<<,_left,_right);
else return search(x<<|,_left,_right);
}
}
void buff(int x,int _left,int _right,int z){
if(tree[x].sleft==_left && tree[x].sright==_right) tree[x].delta=z,stev(x);
else{
if(tree[x].delta!=-){
tree[x<<].delta=tree[x<<|].delta=tree[x].delta; tree[x].delta=-;
stev(x<<),stev(x<<|);
tree[x].delta=-;
}
if(_left<=tree[x].mid && _right>tree[x].mid) buff(x<<,_left,tree[x].mid,z),buff(x<<|,tree[x].mid+,_right,z);
else if(_right<=tree[x].mid) buff(x<<,_left,_right,z);
else buff(x<<|,_left,_right,z);
tree[x].svalue=tree[x<<].svalue+tree[x<<|].svalue;
}
}
int install(int x){
int ans=;
while(x!=-){
ans+=fan_xv[x]-fan_xv[top[x]]+-search(,fan_xv[top[x]],fan_xv[x]);
buff(,fan_xv[top[x]],fan_xv[x],);
//x=father[x] 我是傻逼qaqqqqqqqqqqqqqqqqqqqq
x=father[top[x]];
}
return ans;
}
int uninstall(int x){
int ans=search(,fan_xv[x],er_xv[x]);
buff(,fan_xv[x],er_xv[x],);
return ans;
}
int main(){
/*freopen("ddd.in","r",stdin);
freopen("ddd.out","w",stdout);*/
freopen("manager.in","r",stdin);
freopen("manager.out","w",stdout);
cin>>n;
for(int i=;i<n;i++) insert(read(),i),n_value[i]=;
dfs1(,-,),dfs2(,),get_SegmentTree(,,n-);
cin>>m;
char ch; int _id;
while(m --> ){//趋向于
ch=getchar();
while(ch!='i' && ch!='u') ch=getchar();
if(ch=='i'){
for(int i=;i<=;i++) ch=getchar();
_id=read();
printf("%d\n",install(_id));
}
else{
for(int i=;i<=;i++) ch=getchar();
_id=read();
printf("%d\n",uninstall(_id));
}
}
return ;
}
【NOI2015】软件包管理器的更多相关文章
- BZOJ 4196: [Noi2015]软件包管理器 [树链剖分 DFS序]
4196: [Noi2015]软件包管理器 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1352 Solved: 780[Submit][Stat ...
- [BZOJ4196][NOI2015]软件包管理器
4196: [Noi2015]软件包管理器 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1040 Solved: 603[Submit][Stat ...
- Bzoj 4196: [Noi2015]软件包管理器 树链剖分
4196: [Noi2015]软件包管理器 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 721 Solved: 419[Submit][Statu ...
- [NOI2015]软件包管理器
4621 [NOI2015]软件包管理器 题目等级 : 钻石 Diamond 题目描述 Description Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过 ...
- BZOJ_4196_[Noi2015]软件包管理器_树链剖分
BZOJ_4196_[Noi2015]软件包管理器_树链剖分 题意: Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助 ...
- bzoj 4196 [Noi2015]软件包管理器 (树链剖分+线段树)
4196: [Noi2015]软件包管理器 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 2852 Solved: 1668[Submit][Sta ...
- 洛谷 P2146 [NOI2015]软件包管理器 解题报告
P2146 [NOI2015]软件包管理器 题目描述 Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件源下载软 ...
- 【BZOJ4196】[Noi2015]软件包管理器 树链剖分
[Noi2015]软件包管理器 树链剖分 Description Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从 ...
- [BZOJ4196][NOI2015]软件包管理器(树链剖分)
4196: [Noi2015]软件包管理器 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 2166 Solved: 1253[Submit][Sta ...
- [Luogu 2146] NOI2015 软件包管理器
[Luogu 2146] NOI2015 软件包管理器 树剖好题. 通过对题目的分析发现,这些软件构成一棵树,\(0\) 是树根. 每下载一个软件,需要下载根到这个软件的路径上的所有软件: 每卸载一个 ...
随机推荐
- 在oracle中创建空间索引
Oracle spatial可以方便的存储空间数据,大量的空间数据必需要使用空间索引去查询.在oracle中创建空间索引必需先建立元数据,否则无法创建索引.创建元数据的代码: insert into ...
- SharePoint 列表应用实例 - 显示约束
博客地址:http://blog.csdn.net/FoxDave 有时会碰到这样的需求,比如上传周报到文档库,周报只能领导和自己看到,其他同事是看不到的.通常我们开发的人遇到这种情况条件反射地想到的 ...
- JVM-class文件完全解析-常量池
在.java文件,讲过javac编译后产生的 .class文件中,头4个字节表示的是魔数,接着魔数后面的第5,6个字节存储的是次版本号,第7,8个字节存储的主板本号.那么再接下来的就是表示常量池入口了 ...
- NTP服务器的配置
安装cloudera Manager的时候,必须要求集群的主机之间时间同步,搭建一个NTP服务器的思路是,首先通过一台主机master与外网进行时间同步,然后其他的slaver主机与主机master进 ...
- 微软TechEd2013大会门票热卖!
微软TechEd2013大会将在北京.上海两地隆重举行! 会议时间安排如下: 北京:12月5日—6日 国家会议中心 上海:12月11日—12日 国际会议中心 现在是门票热卖时期,票价:2688.0 ...
- uitabbarcontroller中 在设置tab bar item的image属性后不显示问题
开始使用ios中的UITabBarController,在给Tab Bar Item设置自定义图片的时候,遇到了问题 按照如下配置: 出来的结果确是: 实际上test24.png应该是: 纠结了很久, ...
- libimobiledevice安装步骤
https://github.com/libimobiledevice/libimobiledevice libimobiledevice安装指南,你还不知道libimobiledevice为何物,赶 ...
- 使用开源工具MonoDevelop开发GTK#图形界面
转自:http://developer.51cto.com/art/201011/235040.htm Mono一直到现在的2.8已经完全可以胜任一些比较小的项目了,但相关的开发文档与教程一直比较匮乏 ...
- BZOJ 2111 排列计数
f[i]=f[l]*f[r]*C(size[l]+size[r],size[l]). 需要lucas. #include<iostream> #include<cstdio> ...
- OD调试篇5--如何应对OD使用中的一些问题
打开小甲鱼给的进行恶搞过的程序,会发现一些问题 发现程序直接暂停,或者加载进来有问题. 那机智的我 通过对上一个没有恶搞过的exe可执行文件的PE头进行了比较 会发现其中的猫腻 那么我们去正常的修改一 ...