description

Linux用户和OSX用户一定对软件包管理器不会陌生。通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件源下载软件包,同时自动解决所有的依赖(即下载安装这个软件包的安装所依赖的其它软件包),完成所有的配置。Debian/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。


analysis

  • 然而可以直接树剖

  • 对于安装软件,就把根到它的路径全部设为\(1\)

  • 从该点一直跳到根,边跳边线段树区间修改

  • 对于卸载软件,就把它和它的子树全部设为\(0\)

  • 这个一次线段树区间修改就可以了

  • 操作前后不同的的数个数,可以拿操作前后的整棵树里的\(1\)的数目相减得到


code

#pragma GCC optimize("O3")
#pragma G++ optimize("O3")
#include<stdio.h>
#include<string.h>
#define MAXN 100005
#define ll long long
#define reg register ll
#define fo(i,a,b) for (reg i=a;i<=b;++i)
#define fd(i,a,b) for (reg i=a;i>=b;--i)
#define rep(i,a) for (reg i=last[a];i;i=next[i]) using namespace std; ll last[MAXN],next[MAXN],tov[MAXN];
ll fa[MAXN],top[MAXN],size[MAXN],depth[MAXN],heavy_son[MAXN];
ll tr[MAXN<<2],bz[MAXN<<2],to_tree[MAXN],to_num[MAXN];
ll n,q,tot;
char s[10]; inline ll read()
{
ll x=0,f=1;char ch=getchar();
while (ch<'0' || '9'<ch){if (ch=='-')f=-1;ch=getchar();}
while ('0'<=ch && ch<='9')x=x*10+ch-'0',ch=getchar();
return x*f;
}
inline ll abs(ll x){return x>0?x:-x;}
inline void link(ll x,ll y){next[++tot]=last[x],last[x]=tot,tov[tot]=y;}
inline void dfs1(ll x)
{
rep(i,x)
{
depth[tov[i]]=depth[x]+1,size[tov[i]]=1,dfs1(tov[i]),size[x]+=size[tov[i]];
if (size[tov[i]]>size[heavy_son[x]])heavy_son[x]=tov[i];
}
}
inline void dfs2(ll x,ll y)
{
if (!x)return;top[x]=y;
to_tree[x]=++tot,to_num[tot]=x,dfs2(heavy_son[x],y);
rep(i,x)if (tov[i]!=heavy_son[x])dfs2(tov[i],tov[i]);
}
inline void maketree(ll t,ll l,ll r)
{
bz[t]=-1;if (l==r)return;
ll mid=(l+r)>>1;maketree(t<<1,l,mid),maketree((t<<1)+1,mid+1,r);
}
inline void downdata(ll t,ll l,ll r)
{
if (bz[t]==-1)return;ll mid=(l+r)>>1;
tr[t<<1]=(mid-l+1)*bz[t],tr[(t<<1)+1]=(r-mid)*bz[t];
bz[t<<1]=bz[(t<<1)+1]=bz[t],bz[t]=-1;
}
inline void tree_modify(ll t,ll l,ll r,ll x,ll y,ll z)
{
if (l==x && y==r){tr[t]=(r-l+1)*z,bz[t]=z;return;}
ll mid=(l+r)>>1;downdata(t,l,r);
if (y<=mid)tree_modify(t<<1,l,mid,x,y,z);
else if (x>mid)tree_modify((t<<1)+1,mid+1,r,x,y,z);
else tree_modify(t<<1,l,mid,x,mid,z),tree_modify((t<<1)+1,mid+1,r,mid+1,y,z);
tr[t]=tr[t<<1]+tr[(t<<1)+1];
}
inline void modify(ll x)
{
while (top[x]!=1)tree_modify(1,1,n,to_tree[top[x]],to_tree[x],1),x=fa[top[x]];
tree_modify(1,1,n,1,to_tree[x],1);
}
int main()
{
//freopen("P2146.in","r",stdin);
freopen("manager.in","r",stdin);
freopen("manager.out","w",stdout);
n=read();fo(i,2,n)link(fa[i]=read()+1,i);
tot=0,dfs1(depth[1]=size[1]=1),
dfs2(1,1),maketree(1,1,n),q=read();
while (q--)
{
scanf("%s",&s);ll x=read()+1,tmp=tr[1];
if (s[0]=='i')
{
modify(x),printf("%lld\n",abs(tr[1]-tmp));
continue;
}
tree_modify(1,1,n,to_tree[x],to_tree[x]+size[x]-1,0);
printf("%lld\n",abs(tr[1]-tmp));
}
return 0;
}

【JZOJ5730】【luoguP2146】【Comet OJC0396】软件包管理器的更多相关文章

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

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

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

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

  3. Mac 系统下类似于 apt-get 的软件包管理器 -- Homebrew

    对于一个习惯了在 Ubuntu 的终端上通过 apt-get 来安装工具软件的我来说,也希望在Mac上找到类似的工具,能很方便的一条命令就能安装所需的软件,而不用手工的去查找下载编译,或者是折腾安装所 ...

  4. BZOJ4196 软件包管理器

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

  5. 【NOI2015】软件包管理器

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

  6. Chocolatey:Windows软件包管理器

    Chocolatey 2016-08-03 https://chocolatey.org/ Chocolatey是一个Windows软件包管理器,就像Nuget或者npm,或者说类似Linux上的ap ...

  7. BZOJ_4196_[NOI2015]_软件包管理器_(树链剖分)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=4196 给出一棵树,树上点权为0或1.u权值为1的条件是从根节点到u路径上的所有点权值都为1.u ...

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

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

  9. noi2015 day1 T2软件包管理器

    noi2015 软件包管理器 Description Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件源下载软 ...

随机推荐

  1. hdu6325 /// 上凸包

    题目大意: 给定n 为n个点 给定n个点的坐标 两个点(xi,yi) (xj,yj)之间的花费是 xi*yj-yi*xj (可能为负数) 要求从点1经过若干个点到点n最小花费的路径 且路径要按x轴方向 ...

  2. 利用dynamic解决匿名对象不能赋值的问题

    原文:利用dynamic解决匿名对象不能赋值的问题 关于匿名对象 匿名对象是.Net Framework 3.0提供的新类型,例如: }; 就是一个匿名类,搭配Linq,可以很灵活的在代码中组合数据, ...

  3. 结对编程项目报告--四则运算CORE

    <!doctype html> sw_lab2.mdhtml {overflow-x: initial !important;}#write, body { height: auto; } ...

  4. JS Window对象 计时器setInterval() 在执行时,从载入页面后每隔指定的时间执行代码。

    计时器setInterval() 在执行时,从载入页面后每隔指定的时间执行代码. 语法: setInterval(代码,交互时间); 参数说明: 1. 代码:要调用的函数或要执行的代码串. 2. 交互 ...

  5. AN之数据集

    一.数据集: 首先介绍数据集参数: 英文简称 英文全称 中文全称 单位 换成正常单位 说明1 说明2 Time Time 时间 小时:分钟       Temp Temperature 温度 摄氏度 ...

  6. shell实现批量创建交叉编译工具软链接

    在学习嵌入式过程中,常常用到交叉编译工具,而原本的交叉工具链比较长,不利于记忆以及使用, 解压后的交叉编译工具链如下图所示 为了更好的使用交叉编译工具与其他开发者保持一致,经常需要用到软链接. NAM ...

  7. ES6-let cont 关键字

    ***let1. 作用: * 与var类似, 用于声明一个变量2. 特点: * 在块作用域内有效 * 不能重复声明 * 不会预处理, 不存在提升3. 应用: * 循环遍历加监听 * 使用let取代va ...

  8. 欧拉定理、欧拉函数、a/b%c

    怕忘了…… 欧拉函数 定义.证明.打表方法 欧拉定理 定义.证明 https://blog.csdn.net/zzkksunboy/article/details/73061013 剩余系.完系.简系 ...

  9. CSS案例2(一个简单的新闻网页)

     知识点: 1.一般网页不用纯黑,用淡灰色  3c3c3c 2.text-align: center;  /*  文字水平居中 */ 3.font-weight: normal;  /* 清除加粗效果 ...

  10. 【NIO】NIO之浅谈内存映射文件原理与DirectMemory

    Java类库中的NIO包相对于IO 包来说有一个新功能是内存映射文件,日常编程中并不是经常用到,但是在处理大文件时是比较理想的提高效率的手段.本文我主要想结合操作系统中(OS)相关方面的知识介绍一下原 ...