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. BZOJ 1002 FJOI 2007 轮状病毒 暴力+找规律+高精度

    题目大意: 思路:基尔霍夫矩阵求生成树个数,不会. 可是能够暴力打表.(我才不会说我调试force调试了20分钟... CODE(force.cc): #include <cstdio> ...

  2. POJ - 3984 - 迷宫问题 (DFS)

    迷宫问题 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10936   Accepted: 6531 Description ...

  3. UITableView去掉最后切割线的一种方法

    UITableView以style:UITableViewStylePlain方式创建时.仅仅要有cell,就会有一条黑线 哪怕至于一个cell也会有,如图 在网上找了集中方法,都不好使,比方http ...

  4. vue18 动画

    <!-- bower-> (前端)包管理器 npm install bower -g 验证: bower --version bower install <包名> bower ...

  5. spring配置 quartz-config.xml

    <!-- 配置调度程序quartz ,其中配置JobDetail有两种方式--> <!-- 使用MethodInvokingJobDetailFactoryBean,任务类可以不实现 ...

  6. Vsftp问题及解决办法汇总(持续增加中)

    1.VsFTP出现500 OOPS: cannot change directory的解决办法 在安装完vsftp服务后登陆时可能遇到cannot change directory后面是登陆者的目录的 ...

  7. 130.C++经典面试题 52-100

  8. 洛谷P2633 Count on a tree

    题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始为0,即第一个 ...

  9. 干货分享 -- Math

    昼猫笔记 JavaScript -- Math Math也是JS的内置对象,但是它不是一个构造函数,它属于一个工具类不用创建对象,它封装了数学运算相关的属性和方法,今天就来写下常用的函数[API(ap ...

  10. R学习:《机器学习与数据科学基于R的统计学习方法》中文PDF+代码

    当前,机器学习和数据科学都是很重要和热门的相关学科,需要深入地研究学习才能精通. <机器学习与数据科学基于R的统计学习方法>试图指导读者掌握如何完成涉及机器学习的数据科学项目.为数据科学家 ...