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,……,Am−1依赖Am,而Am依赖A1,则称这m个软件包的依赖关系构成环),当然也不会有一个软件包依赖自己。
现在你要为你的软件包管理器写一个依赖解决程序。根据反馈,用户希望在安装和卸载某个软件包时,快速地知道这个操作实际上会改变多少个软件包的安装状态(即安装操作会安装多少个未安装的软件包,或卸载操作会卸载多少个已安装的软件包),你的任务就是实现这个部分。注意,安装一个已安装的软件包,或卸载一个未安装的软件包,都不会改变任何软件包的安装状态,即在此情况下,改变安装状态的软件包数为0。

Input

输入文件的第1行包含1个正整数n,表示软件包的总数。软件包从0开始编号。

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

Output

输出文件包括q行。

输出文件的第i行输出1个整数,为第i步操作中改变安装状态的软件包数。
 

Sample Input

7
0 0 0 1 1 5
5
install 5
install 6
uninstall 1
install 4
uninstall 0

Sample Output

3
1
3
2
3

解题思路:

显然这是一棵树。

支持询问到根节点有多少点被标记,清空子树标记。

一颗线段树,支持区间改为1/0。

维护树链剖分序即可。

然而被卡常,开了O2才过,好蒟蒻啊QAQ

代码:

 #pragma GCC optimize(2)
#include<cstdio>
#include<cstring>
#include<algorithm>
#define lll spc<<1
#define rrr spc<<1|1
inline int read()
{
int l=;
int ret=;
char ch=getchar();
while(ch<''||ch>'')
{
if(ch=='-')
l=-l;
ch=getchar();
}
while(ch<=''&&ch>='')
{
ret=ret*+ch-'';
ch=getchar();
}
return ret*l;
}
struct trnt{
int val;
int len;
int lzt;
bool chg;
}tr[];
struct pnt{
int hd;
int fa;
int dp;
int tp;
int ind;
int mxs;
int wgt;
}p[];
struct ent{
int twd;
int lst;
}e[];
int cnt;
int n,m;
int dfn;
char cmd[];
void ade(int f,int t)
{
cnt++;
e[cnt].twd=t;
e[cnt].lst=p[f].hd;
p[f].hd=cnt;
}
void pushup(int spc)
{
tr[spc].val=tr[lll].val+tr[rrr].val;
tr[spc].len=tr[lll].len+tr[rrr].len;
return ;
}
void Add(int spc,int x)
{
tr[spc].val=tr[spc].len*x;
tr[spc].lzt=x;
tr[spc].chg=;
return ;
}
void pushdown(int spc)
{
if(tr[spc].chg)
{
Add(lll,tr[spc].lzt);
Add(rrr,tr[spc].lzt);
tr[spc].chg=;
}
return ;
}
void build(int l,int r,int spc)
{
if(l==r)
{
tr[spc].len=;
return ;
}
int mid=(l+r)>>;
build(l,mid,lll);
build(mid+,r,rrr);
pushup(spc);
return ;
}
void update(int l,int r,int ll,int rr,int spc,int v)
{
if(l>rr||ll>r)
return ;
if(ll<=l&&r<=rr)
{
Add(spc,v);
return ;
}
pushdown(spc);
int mid=(l+r)>>;
update(l,mid,ll,rr,lll,v);
update(mid+,r,ll,rr,rrr,v);
pushup(spc);
return ;
}
int query(int l,int r,int ll,int rr,int spc)
{
if(ll>r||l>rr)
return ;
if(ll<=l&&r<=rr)
return tr[spc].val;
pushdown(spc);
int mid=(l+r)>>;
return query(l,mid,ll,rr,lll)+query(mid+,r,ll,rr,rrr);
}
void Basic_dfs(int x,int f)
{
p[x].fa=f;
p[x].dp=p[f].dp+;
p[x].wgt=;
int maxs=-;
for(int i=p[x].hd;i;i=e[i].lst)
{
int to=e[i].twd;
if(to==f)
continue;
Basic_dfs(to,x);
p[x].wgt+=p[to].wgt;
if(maxs<p[to].wgt)
{
maxs=p[to].wgt;
p[x].mxs=to;
}
}
return ;
}
void Build_dfs(int x,int top)
{
if(!x)
return ;
p[x].ind=++dfn;
p[x].tp=top;
Build_dfs(p[x].mxs,top);
for(int i=p[x].hd;i;i=e[i].lst)
{
int to=e[i].twd;
if(p[to].ind)
continue;
Build_dfs(to,to);
}
}
int Install(int x)
{
int ans=;
while(p[x].tp!=)
{
ans+=p[x].dp-p[p[x].tp].dp-query(,dfn,p[p[x].tp].ind,p[x].ind,)+;
update(,dfn,p[p[x].tp].ind,p[x].ind,,);
x=p[p[x].tp].fa;
}
ans+=p[x].dp-query(,dfn,p[].ind,p[x].ind,);
update(,dfn,p[].ind,p[x].ind,,);
return ans;
}
int Uninstall(int x)
{
int ans=query(,dfn,p[x].ind,p[x].ind+p[x].wgt-,);
update(,dfn,p[x].ind,p[x].ind+p[x].wgt-,,);
return ans;
}
int main()
{
n=read();
for(int i=;i<=n;i++)
{
int x=read();
x++;
ade(x,i);
ade(i,x);
}
dfn=;
Basic_dfs(,);
Build_dfs(,);
build(,dfn,);
m=read();
while(m--)
{
scanf("%s",cmd+);
int x=read();
x++;
if(cmd[]=='i')
printf("%d\n",Install(x));
else
printf("%d\n",Uninstall(x));
}
return ;
}

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. Thumb指令集与ARM指令集的差别

    Thumb指令集          Thumb指令能够看做是ARM指令压缩形式的子集.是针对代码密度[1]的问题而提出的.它具有16为的代码密度.Thumb不是一个完整的体系结构,不能指望处理程序仅仅 ...

  2. Linux Sendfile 的优势

    Sendfile 函数在两个文件描写叙述符之间直接传递数据(全然在内核中操作,传送),从而避免了内核缓冲区数据和用户缓冲区数据之间的拷贝,操作效率非常高,被称之为零拷贝. Sendfile 函数的定义 ...

  3. modSecurity规则学习(八)——防止CC攻击

    modSecurity日志收集:在phase 5阶段处理. 由于CC攻击主要考虑对动态请求的防护,所以要排除静态资源的请求,或者自定义动态请求的后缀或者关键字做接口针对性的防护. 定义需要排除的请求u ...

  4. SpringBoot结合MongoDB入门

    MongoDB 是一个基于分布式文件存储的数据库.由 C++ 语言编写.旨在为 WEB 应用提供可扩展的高性能数据存储解决方案. MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系 ...

  5. SQL try catch处理

    ALTER PROC usp_AccountTransaction @AccountNum INT, @Amount DECIMAL AS BEGIN BEGIN TRY --Start the Tr ...

  6. SQL语句查询数据库所有表和所有字段的详细信息(包括表描述和字段描述)

    select (case then ddd.value else '' end ) as "表名(中文)" --如果表名相同就返回空 , (case then d.name els ...

  7. Deepin for Linux 下串口调试交换机

    最近因工作需要,在淘宝购买了一条宇泰的串口线:USB to RS232 之所以选择这款,主要是它支持 Windows.Linux.mac Linux机是Deepin for Linux,算是国产比较好 ...

  8. AJAX 前后端交互 验证信息是否正确

    1.前段: function checkPtCode(obj){ $.ajax({ type: "post", url: "xxxxxxx", data: {& ...

  9. 【TC SRM 718 DIV 2 A】RelativeHeights

    [Link]: [Description] 给你n个数字组成原数列; 然后,让你生成n个新的数列a 其中第i个数列ai为删掉原数列中第i个数字后剩余的数字组成的数列; 然后问你这n个数列组成的排序数组 ...

  10. 【Linux环境编程】获取网卡的实时网速

    在windows以下.我们能够看到360或者是qq安全卫士的"安全球".上面显示实时的网速情况.那么在linux里面怎样获取网卡的实时网速?事实上原理非常easy,读取须要获取网速 ...