点此看题面

大致题意: 有\(n\)个软件包,它们的依赖关系形成一棵树。现在,问你安装或卸载一个软件包,会影响多少个软件包的安装状态。

树链剖分

这道题应该是 树链剖分 算法比较入门的题目吧。

对于安装操作

我们对安装和卸载两种操作分别处理。

首先,让我们来看一看安装操作应该如何实现。

考虑到要安装一个软件包,就要把它所依赖的软件包,它的依赖所依赖的软件包,一直到\(0\)号软件包,全部安装。

如果将题目中给出的关系看成一棵树,那么也就是要把这个软件包到\(0\)号节点(即 根节点 )的路径上的所有软件包全部安装。

用树链剖分应该可以轻松做到这一点。

对于卸载操作

我们再来看看如何实现卸载操作。

考虑卸掉一个软件包,那么所有依赖于它的软件包将全被卸载,所有依赖于依赖于它的软件包的软件包,也将全被卸载,以此类推。

不难想到,这就相当于把以这个软件包为根的子树内的所有软件包给卸载了。

用树链剖分应该也能很轻松做到这一点。

代码

#include<bits/stdc++.h>
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
#define abs(x) ((x)<0?-(x):(x))
#define LL long long
#define ull unsigned long long
#define swap(x,y) (x^=y,y^=x,x^=y)
#define N 100000
#define add(x,y) (e[++ee].nxt=lnk[x],e[lnk[x]=ee].to=y)
using namespace std;
int n,ee=0,lnk[N+5];
struct edge
{
int to,nxt;
}e[2*N+5];
class FIO
{
private:
#define Fsize 100000
#define tc() (FinNow==FinEnd&&(FinEnd=(FinNow=Fin)+fread(Fin,1,Fsize,stdin),FinNow==FinEnd)?EOF:*FinNow++)
#define pc(ch) (FoutSize<Fsize?Fout[FoutSize++]=ch:(fwrite(Fout,1,FoutSize,stdout),Fout[(FoutSize=0)++]=ch))
int f,FoutSize,OutputTop;char ch,Fin[Fsize],*FinNow,*FinEnd,Fout[Fsize],OutputStack[Fsize];double w;
public:
FIO() {FinNow=FinEnd=Fin;}
inline void read(int &x) {x=0,f=1;while(!isdigit(ch=tc())) f=ch^'-'?1:-1;while(x=(x<<3)+(x<<1)+(ch&15),isdigit(ch=tc()));x*=f;}
inline void read_char(char &x) {while(isspace(x=tc()));}
inline void read_string(string &x) {x="";while(isspace(ch=tc()));while(x+=ch,!isspace(ch=tc()));}
inline void write(int x) {if(!x) return (void)pc('0');if(x<0) pc('-'),x=-x;while(x) OutputStack[++OutputTop]=x%10+48,x/=10;while(OutputTop) pc(OutputStack[OutputTop]),--OutputTop;}
inline void write_char(char x) {pc(x);}
inline void write_string(string x) {register int i,len=x.length();for(i=0;i<len;++i) pc(x[i]);}
inline void end() {fwrite(Fout,1,FoutSize,stdout);}
}F;
class TreeChainDissection//树链剖分模板
{
private:
#define PushUp(x) (Sum[x]=Sum[x<<1]+Sum[x<<1|1])
#define PushDown(x,ln,rn) ((~flag[x]?(flag[x]?(Sum[x<<1]=ln,Sum[x<<1|1]=rn,flag[x<<1]=flag[x<<1|1]=1):(Sum[x<<1]=Sum[x<<1|1]=flag[x<<1]=flag[x<<1|1]=0)):0),flag[x]=-1)
int d,fa[N+5],son[N+5],sz[N+5],Top[N+5],dfn[N+5],fac[N+5],Depth[N+5],Sum[N<<2],flag[N<<2];
inline void dfs1(int x)//第一遍dfs预处理
{
register int i;
for(sz[x]=1,i=lnk[x];i;i=e[i].nxt)
{
if(!(fa[x]^e[i].to)) continue;
fa[e[i].to]=x,Depth[e[i].to]=Depth[x]+1,dfs1(e[i].to),sz[x]+=sz[e[i].to];
if(sz[e[i].to]>sz[son[x]]) son[x]=e[i].to;
}
}
inline void dfs2(int x,int col)//第二遍dfs预处理
{
register int i;
if(son[fac[dfn[x]=++d]=x]) dfs2(son[x],col);
for(Top[x]=col,i=lnk[x];i;i=e[i].nxt)
{
if(!(fa[x]^e[i].to&&son[x]^e[i].to)) continue;
dfs2(e[i].to,e[i].to);
}
}
inline void Build(int l,int r,int rt)//建树
{
flag[rt]=-1;
if(l^r)
{
register int mid=l+r>>1;
if(l<=mid) Build(l,mid,rt<<1);
if(r>mid) Build(mid+1,r,rt<<1|1);
}
}
inline int Update(int l,int r,int rt,int ul,int ur,int x)//将[ul...ur]区间内所有软件包的安装状态修改为x(x=0表示未安装,x=1表示安装),并返回需要改变安装状态的软件包数
{
register int res=0;
if(ul<=l&&r<=ur) {register int t;(x?(t=r-l+1,flag[rt]=1):(t=0,flag[rt]=0)),res=abs(t-Sum[rt]),Sum[rt]=t;return res;}
register int mid=l+r>>1;
PushDown(rt,mid-l+1,r-mid);
if(ul<=mid) res=Update(l,mid,rt<<1,ul,ur,x);
if(ur>mid) res+=Update(mid+1,r,rt<<1|1,ul,ur,x);
PushUp(rt);
return res;
}
public:
inline void Init() {dfs1(1),dfs2(1,1),Build(1,n,1);}
inline int uninstall(int pos) {return Update(1,n,1,dfn[pos],dfn[pos]+sz[pos]-1,0);}//卸载一个软件包,相当于修改以这个软件包为根节点的子树内所有软件包安装状态为0
inline int install(int pos)//安装一个软件包,相当于修改这个软件包到根节点的所有软件包安装状态为1
{
register int res=0;
while(Top[pos]>>1) res+=Update(1,n,1,dfn[Top[pos]],dfn[pos],1),pos=fa[Top[pos]];
return res+Update(1,n,1,1,dfn[pos],1);
}
}S;
int main()
{
register int i,Q,x;register char op;
for(F.read(n),i=2;i<=n;++i) F.read(x),add(x+1,i);
for(S.Init(),F.read(Q);Q;--Q)
{
F.read_char(op),F.read(x);
if(op^'u') F.write(S.install(x+1)),F.write_char('\n');//对于安装操作
else F.write(S.uninstall(x+1)),F.write_char('\n');//对于卸载操作
}
return F.end(),0;
}

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

  1. [BZOJ4196][NOI2015]软件包管理器(树链剖分)

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

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

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

  3. bzoj4196 [Noi2015]软件包管理器——树链剖分

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4196 树链剖分. 代码如下: #include<iostream> #inclu ...

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

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

  5. bzoj4196 [Noi2015]软件包管理器 树链剖分+线段树

    先把树剖分了(又是dfs1.dfs2),然后区间求和.区间覆盖即可 难得的1A好(shui)题 ——写了那么多题,终于有一道是1A的了,加上上一次连续交了几遍A的程序,我的状态莫名好看啊233 总结: ...

  6. 【BZOJ4196】[Noi2015]软件包管理器 树链剖分

    [Noi2015]软件包管理器 树链剖分 Description Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从 ...

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

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

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

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

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

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

  10. 洛谷 P2146 [NOI2015]软件包管理器 树链剖分

    目录 题面 题目链接 题目描述 输入输出格式 输入格式: 输出格式: 输入输出样例 输入样例#1: 输出样例#1: 输入样例#2: 输出样例#2: 说明 说明 思路 AC代码 总结 题面 题目链接 P ...

随机推荐

  1. hdu6053(莫比乌斯+容斥+分块)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=6053 题意: 给出一个含 n 个元素的 a 数组, 求 bi <= ai 且 gcd(b1, ...

  2. 洛谷P5048 [Ynoi2019模拟赛]Yuno loves sqrt technology III(分块)

    传送门 众所周知lxl是个毒瘤,Ynoi道道都是神仙题 用蒲公英那个分块的方法做结果两天没卡过去→_→ 首先我们分块,预处理块与块之间的答案,然后每次询问的时候拆成整块和两边剩下的元素 整块的答案很简 ...

  3. 大部分人的努力程度之低,根本轮不到拼天赋-----作者meiya

            格式的正确与否,直接影响了人得阅读感受. 看到书写格式正确,分段清楚,没有错别字,叙事有条理的邮件只有寥寥几封,大多都是一段到底,标点混乱,表达不清,主题不明,短短三行就有两个错别字. ...

  4. 初识Scrapy之再续火影情缘

    前言Scrapy框架之初窥门径1 Scrapy简介2 Scrapy安装3 Scrapy基础31 创建项目32 Shell分析4 Scrapy程序编写41 Spiders程序测试42 Items编写43 ...

  5. mongodb you can't add a second

    问题信息: Due to limitations of the com.mongodb.BasicDBObject, you can't add a second 'createTime' expre ...

  6. 洛谷P2846 光开关Light Switching

    题目描述 灯是由高科技--外星人鼠标操控的.你只要左击两个灯所连的鼠标, 这两个灯,以及之间的灯都会由暗变亮,或由亮变暗.右击两个灯所连的鼠 标,你就可以知道这两个灯,以及之间的灯有多少灯是亮的.起初 ...

  7. jmeter小问题解决方案合集

    问题1.在http请求,post的body中输入中文,显示乱码,怎么解决? 在jmeter的bin目录下,找到这个文件jmeter.properties,把jsyntaxtextarea.font.f ...

  8. Vs 排除的文件➕ 添加回项目。。。。

    显示所有文件之后吧,就能看到排除掉的文件了.右键之前的文件,包括在项目中即可.

  9. Cannot add or update a child row:

    两个 表 数据 不一致... 含有 约束 的 表 中 所有 id 都应该 在 主 表 中 可以 找到---

  10. jquery——尺寸

    1. 获取和设置元素的尺寸 2. 获取元素相对页面的绝对位置:offset() 这种方式增加的盒子不会对之前的结构产生影响 demo: <!DOCTYPE html> <html l ...