BZOJ_4196_[NOI2015]_软件包管理器_(树链剖分)
描述
http://www.lydsy.com/JudgeOnline/problem.php?id=4196
给出一棵树,树上点权为0或1.u权值为1的条件是从根节点到u路径上的所有点权值都为1.u权值为0的条件为u的子树中所有节点权值都为0,进行如下两种操作:
1.install u.将u改为1.
2.uninstall u.将u改为0.
每次操作输出执行此操作需要改动的点的个数,并进行改动操作.
4196: [Noi2015]软件包管理器
Time Limit: 10 Sec Memory Limit: 512 MB
Submit: 991 Solved: 572
[Submit][Status][Discuss]
Description
Linux
用户和OSX用户一定对软件包管理器不会陌生。通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件源下载软件包,同
时自动解决所有的依赖(即下载安装这个软件包的安装所依赖的其它软件包),完成所有的配置。Debian/Ubuntu使用的apt-
get,Fedora/CentOS使用的yum,以及OSX下可用的homebrew都是优秀的软件包管理器。
件包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开始编号。
Output
输出文件包括q行。
Sample Input
0 0 0 1 1 5
5
install 5
install 6
uninstall 1
install 4
uninstall 0
Sample Output
1
3
2
3
HINT
一开始所有的软件包都处于未安装状态。
Source
分析
两种操作:路径操作和子树操作.树链剖分用线段树维护.
路径操作:直接向上一直走到根节点即可.
子树操作:注意到树链剖分结束后,对于节点u,u的子树中的所有节点的tid值都大于tid[u],因为它们是在u之后访问的,并且子树中所有点的tid值是连续的,因为从u点开始,直到返回u点,访问整个子树的时候,tid值每次+1,故值时连续的.所以可以记录子树中的tid的最大值,即将整个子树转化为区间后的区间右端点(左端点为u).那进行子树操作的时候进行区间操作就可以了.比路径操作更简单.
注意:
1.线段树操作的时候要注意l<=r(tid[top[u]]要卸载tid[u]的前面,因为tid[top[u]]<=tid[u])(好像这个地方错了不止一次了= =).
ps.
1.从这次开始都用静态链表来代替vector了,讲真比vector快= =.做的时候结构体中放原本放在vector中的参量,再多放一个next,结构体数组g的大小为边的数量,再开一个大小为点的数量的head数组,head[u]用来代表从u出发的边中的第一条边在结构体数组g中编号.
#include <cstdio>
#include <algorithm> using namespace std; const int maxn=+; int n,q;
int dep[maxn];
int prt[maxn];
int size[maxn];
int son[maxn];
int top[maxn];
int tid[maxn];
int rev_tid[maxn];
int r[maxn]; struct Edge{
int head[maxn];
struct edge{
int to,next;
edge(){}
edge(int a,int b):to(a),next(b){}
}g[maxn]; void insert(int from,int to,int id){
g[id]=edge(to,head[from]);
head[from]=id;
}
}G; struct Segment_Tree{
struct node{
int l,r,x,s;
}a[*maxn]; void build_tree(int l,int r,int k){
a[k].l=l; a[k].r=r; a[k].x=; a[k].s=;
if(l==r) return;
int mid=l+(r-l)/;
build_tree(l,mid,*k); build_tree(mid+,r,*k+);
} inline void push_down(int k)
{
if(a[k].s!=-){
a[*k].s=a[k].s; a[*k].x=a[k].s?a[*k].r-a[*k].l+:;
a[*k+].s=a[k].s; a[*k+].x=a[k].s?a[*k+].r-a[*k+].l+:;
}
} inline void push_up(int k)
{
a[k].x=a[*k].x+a[*k+].x;
a[k].s=(a[*k].s==a[*k+].s&&a[*k].s!=-)?a[*k].s:-;
} int search(int l,int r,int k,int t){
if(a[k].l==l&&a[k].r==r){
int ans=t?a[k].x:r-l+-a[k].x;
a[k].s=t?:;
a[k].x=t?:r-l+;
return ans;
}
int mid=a[k].l+(a[k].r-a[k].l)/;
push_down(k);
int ans;
if(r<=mid) ans=search(l,r,*k,t);
else if(l>mid) ans=search(l,r,*k+,t);
else ans=search(l,mid,*k,t)+search(mid+,r,*k+,t);
push_up(k);
return ans;
}
}T; void find_h_e(int u,int p,int d){
prt[u]=p; dep[u]=d; size[u]=;
int max_size=;
for(int i=G.head[u];i;i=G.g[i].next){
int v=G.g[i].to;
find_h_e(v,u,d+);
size[u]+=size[v];
if(size[v]>max_size){
max_size=size[v];
son[u]=v;
}
}
} void conect_h_e(int u,int anc,int &k){
top[u]=anc; tid[u]=++k; rev_tid[k]=u;
if(son[u]) conect_h_e(son[u],anc,k);
for(int i=G.head[u];i;i=G.g[i].next){
int v=G.g[i].to;
if(v!=son[u]){
conect_h_e(v,v,k);
}
}
r[u]=rev_tid[k];
} int get_sum1(int u){
int sum_now=;
while(top[u]!=){
sum_now+=T.search(tid[top[u]],tid[u],,);
u=prt[top[u]];
}
sum_now+=T.search(,tid[u],,);
return sum_now;
} int get_sum2(int u){return T.search(tid[u],tid[r[u]],,);} void solve(){
scanf("%d",&q);
for(int i=;i<=q;i++){
char c[]; scanf("%s",c);
int u; scanf("%d",&u);
if(c[]=='i') printf("%d\n",get_sum1(u));
else printf("%d\n",get_sum2(u)); }
} void init(){
scanf("%d",&n);
for(int i=;i<n;i++){
int from;
scanf("%d",&from);
G.insert(from,i,i);
}
} int main(){
#ifndef ONLINE_JUDGE
freopen("3.in","r",stdin);
freopen("3.out","w",stdout);
#endif
init();
find_h_e(,,);
int k=;
conect_h_e(,,k);
T.build_tree(,n,);
solve();
#ifndef ONLINE_JUDGE
fclose(stdin);
fclose(stdout);
system("3.out");
#endif
return ;
}
BZOJ_4196_[NOI2015]_软件包管理器_(树链剖分)的更多相关文章
- 【BZOJ4196】【NOI2015】软件包管理器(树链剖分,线段树)
[BZOJ4196][NOI2015]软件包管理器 题面 题目描述 Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你 ...
- 【BZOJ4196】[NOI2015] 软件包管理器(树链剖分)
点此看题面 大致题意: 有\(n\)个软件包,它们的依赖关系形成一棵树.现在,问你安装或卸载一个软件包,会影响多少个软件包的安装状态. 树链剖分 这道题应该是 树链剖分 算法比较入门的题目吧. 对于安 ...
- 「NOI2015」「Codevs4621」软件包管理器(树链剖分
4621 [NOI2015]软件包管理器 时间限制: 1 s 空间限制: 256000 KB 题目等级 : 钻石 Diamond 题目描述 Description Linux用户和OSX用户一定对 ...
- 4196. [NOI2015]软件包管理器【树链剖分】
Description Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件源下载软件包,同时自动解决所有的依赖( ...
- 洛谷 P2146 [NOI2015]软件包管理器 (树链剖分模板题)
题目描述 Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件源下载软件包,同时自动解决所有的依赖(即下载安装这个 ...
- BZOJ4196: [Noi2015]软件包管理器(树链剖分)
Description Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件源下载软件包,同时自动解决所有的依赖( ...
- [NOI2015]软件包管理器(树链剖分,线段树)
题目描述 Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件源下载软件包,同时自动解决所有的依赖(即下载安装这个 ...
- [NOI2015] 软件包管理器【树链剖分+线段树区间覆盖】
Online Judge:Luogu-P2146 Label:树链剖分,线段树区间覆盖 题目大意 \(n\)个软件包(编号0~n-1),他们之间的依赖关系用一棵含\(n-1\)条边的树来描述.一共两种 ...
- 洛谷P2146 [NOI2015]软件包管理器 题解 树链剖分+线段树
题目链接:https://www.luogu.org/problem/P2146 本题涉及算法: 树链剖分: 线段树(区间更新及求和,涉及懒惰标记) 然后对于每次 install x ,需要将 x 到 ...
- 【Luogu】P2146软件包管理器(树链剖分)
题目链接 上午跟rqy学了一道超难的概率题,准备颓一会,于是水了这么一道水题. 话说这题真的是模板啊.数据范围正好,描述特别贴近(都不给你绕弯子的),连图都给你画出来,就差题目描述加一句“树链剖分模板 ...
随机推荐
- SQL语句一点小心得
在Sqlserver中 if 语句后面的语句加begin end 括起来 问题:执行速度问题,在存储过程中没有加begin end 执行速度很慢,加了begin end执行速度加快 ALTER PRO ...
- Oracle中用一张表的字段更新另一张表的字段
今天在做项目的过程中,发现开发库中某张表的某字段有许多值是空的,而测试库中该字段的值则是有的. 那么,有什么办法能将测试库中该字段的值更新到开发库中呢? SQL Server中这是比较容易解决的,而O ...
- Content by query webpart 自定义样式的使用方法
今天研究一个非常实用的webpart 如果在office365 上 的webpart中一直没“内容查询”, 这里需要开启2个features:http://community.office365.co ...
- sql中truncate 、delete与drop区别
SQL truncate .delete与drop区别 相同点: 1.truncate和不带where子句的delete.以及drop都会删除表内的数据. 2.drop.truncate都是DDL ...
- visual studio vs2010 vs2013 显示详细调试信息方法;vs debug 出错怎么办,你需要的不是答案,是方法。
显示详细的输出信息: 选项--项目和解决方案--生成并运行--MSBuild项目生成输出详细信息: 这样在输出目录就会显示详细的错误信息,可以自己分析了.
- git revert all changes
点击打开链接https://www.kernel.org/pub/software/scm/git/docs/git-reset.html # Revert changes to modified f ...
- 《sed的流艺术之一》-linux命令五分钟系列之二十一
本原创文章属于<Linux大棚>博客,博客地址为http://roclinux.cn.文章作者为rocrocket. 为了防止某些网站的恶性转载,特在每篇文章前加入此信息,还望读者体谅. ...
- BFC与hasLayout之间的故事
刚拒绝了一个很有诱惑的公司,不是不想去,而是对现在的能力还不确定,希望能够进一步提高自己的技能,所有想写博客了,监督自己的学习进度·········现在还没有开放博客,希望成熟一些后再开放吧! 进入正 ...
- C语言之程序结构
一个好的程序首先要有好的程序结构,我从变量和结构两个方面来做分析. 一.浅谈程序中的变量 一个程序架构最基本的就是程序变量,谈到程序中的变量,我们应该考虑两部分,一方面是变量的作用域,一方面是变量的生 ...
- Xcode7 修改bundle identifier
Xcode 7 与之前的版本在修改bundle identifier的时候一点需要注意: 除了需要在.plist文件中修改, 还需要在 build setting中的 Product Bundle I ...