【树链剖分(区间线段树)】BZOJ4196-[NOI2015]软件包管理
【题目大意】
如果软件包A依赖软件包B,那么安装软件包A以前,必须先安装软件包B。同时,如果想要卸载软件包B,则必须卸载软件包A。而且,由于你之前的工作,除0号软件包以外,在你的管理器当中的软件包都会依赖一个且仅一个软件包,而0号软件包不依赖任何一个软件包。依赖关系不存在环。求出在安装和卸载某个软件包时,实际上会改变多少个软件包的安装状态(即安装操作会安装多少个未安装的软件包,或卸载操作会卸载多少个已安装的软件包。(注意,安装一个已安装的软件包,或卸载一个未安装的软件包,都不会改变任何软件包的安装状态,即在此情况下,改变安装状态的软件包数为0)
【思路】
裸的树剖...然而我发现我写错了区间覆盖的线段树,要设置两个标记,一个记录该区间是否需要修改,另一个记录该区间覆盖的值。
话说BZOJ要用printf否则会RE,我怎么不长记性呢………
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
const int MAXN=+;
const int rt=;
vector<int> E[MAXN];
int n;
int fa[MAXN],dep[MAXN],hson[MAXN],size[MAXN];
int cnt=,top[MAXN],pos[MAXN];
int sum[MAXN<<],add[MAXN<<],change[MAXN<<]; //树链剖分部分
void addedge(int u,int v)
{
E[u].push_back(v);
} void dfs1(int u,int father,int depth)
{
fa[u]=father;
dep[u]=depth;
size[u]=;
hson[u]=-;
for (int i=;i<E[u].size();i++)
{
int to=E[u][i];
dfs1(to,u,depth+);
size[u]+=size[to];
if (hson[u]==- || size[to]>size[hson[u]]) hson[u]=to;
}
} void dfs2(int u,int t)
{
pos[u]=++cnt;
top[u]=t;
if (hson[u]!=-) dfs2(hson[u],t);
for (int i=;i<E[u].size();i++)
{
int to=E[u][i];
if (to!=hson[u]) dfs2(to,to);
}
} //线段树部分
void build()
{
memset(sum,,sizeof(sum));
memset(add,,sizeof(add));
} void pushup(int rt)
{
sum[rt]=sum[rt<<]+sum[rt<<|];
} void pushdown(int rt,int m)
{
if (change[rt])
{
change[rt<<]=change[rt<<|]=;
add[rt<<]=add[rt];
add[rt<<|]=add[rt];
sum[rt<<]=add[rt]*(m-(m>>));
sum[rt<<|]=add[rt]*(m>>);
add[rt]=change[rt]=;
}
} int query_sum(int L,int R,int l,int r,int rt)
{
if (L<=l && r<=R) return sum[rt];
pushdown(rt,r-l+);
int m=(l+r)>>;
int ret=;
if (m>=L) ret+=query_sum(L,R,lson);
if (m<R) ret+=query_sum(L,R,rson);
pushup(rt);
return ret;
} void modify(int L,int R,int l,int r,int rt,int x)
{
if (L<=l && r<=R)
{
change[rt]=;
add[rt]=x;
sum[rt]=(r-l+)*x;
return;
}
pushdown(rt,r-l+);
int m=(l+r)>>;
if (m>=L) modify(L,R,lson,x);
if (m<R) modify(L,R,rson,x);
pushup(rt);
} //树链剖分查询部分
int install(int x,int y)
{
int ret=dep[x],f1=top[x],f2=top[y];
while (f1!=f2)
{
ret-=query_sum(pos[f1],pos[x],,n,);
modify(pos[f1],pos[x],,n,,);
x=fa[f1];
f1=top[x];
}
ret-=query_sum(pos[y],pos[x],,n,);
modify(pos[y],pos[x],,n,,);
return (ret);
} int uninstall(int x)
{
int ret=query_sum(pos[x],pos[x]+size[x]-,,n,);
modify(pos[x],pos[x]+size[x]-,,n,,);
return ret;
} //读入部分
void init()
{
scanf("%d",&n);
for (int i=;i<n;i++)
{
int tmp;
scanf("%d",&tmp);
addedge(tmp,i);
}
dfs1(,,);
dfs2(,);
} void get_ans()
{
memset(sum,,sizeof(sum));
memset(change,,sizeof(change));
memset(add,,sizeof(add));
int q;
scanf("%d",&q);
for (int i=;i<q;i++)
{
char str[];
int x;
scanf("%s%d",str,&x);
if (str[]=='i') printf("%d\n",install(x,rt));
else if (str[]=='u') printf("%d\n",uninstall(x));
}
} int main()
{
init();
build();
get_ans();
return ;
}
【树链剖分(区间线段树)】BZOJ4196-[NOI2015]软件包管理的更多相关文章
- [bzoj4196][Noi2015]软件包管理器_树链剖分_线段树
		
软件包管理器 bzoj-4196 Noi-2015 题目大意:Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件 ...
 - bzoj 4034 [HAOI2015] T2(树链剖分,线段树)
		
4034: [HAOI2015]T2 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1536 Solved: 508[Submit][Status] ...
 - bzoj 3626 [LNOI2014]LCA(离线处理+树链剖分,线段树)
		
3626: [LNOI2014]LCA Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1272 Solved: 451[Submit][Status ...
 - 【BZOJ3531】旅行(树链剖分,线段树)
		
[BZOJ3531]旅行(树链剖分,线段树) 题面 Description S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足 从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教 ...
 - bzoj 1036 [ZJOI2008]树的统计Count(树链剖分,线段树)
		
1036: [ZJOI2008]树的统计Count Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 10677 Solved: 4313[Submit ...
 - poj 3237 Tree(树链剖分,线段树)
		
Tree Time Limit: 5000MS Memory Limit: 131072K Total Submissions: 7268 Accepted: 1969 Description ...
 - bzoj 2243 [SDOI2011]染色(树链剖分,线段树)
		
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 4637 Solved: 1726[Submit][Status ...
 - HDU 4366 Successor(树链剖分+zkw线段树+扫描线)
		
[题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=4366 [题目大意] 有一个公司,每个员工都有一个上司,所有的人呈树状关系,现在给出每个人的忠诚值和 ...
 - 【BZOJ5507】[GXOI/GZOI2019]旧词(树链剖分,线段树)
		
[BZOJ5507][GXOI/GZOI2019]旧词(树链剖分,线段树) 题面 BZOJ 洛谷 题解 如果\(k=1\)就是链并裸题了... 其实\(k>1\)发现还是可以用类似链并的思想,这 ...
 - 【洛谷5439】【XR-2】永恒(树链剖分,线段树)
		
[洛谷5439][XR-2]永恒(树链剖分,线段树) 题面 洛谷 题解 首先两个点的\(LCP\)就是\(Trie\)树上的\(LCA\)的深度. 考虑一对点的贡献,如果这两个点不具有祖先关系,那么这 ...
 
随机推荐
- 安卓topbar编码实战
			
1.先在res->value下新建attrs.xml文件 <?xml version="1.0" encoding="utf-8"?> < ...
 - DSP投放进阶指南
 - tomcat发布web项目的三种方式
			
tomcat发布web项目的三种方式 方式一: 配置tomcat 安装目录下的conf/server.xml <Host name="loaclhost">标签里面添加 ...
 - mavne问题解决---Dynamic Web Module 2.3 or newer
			
一:前沿 maven问题的bug,其实是很烦人的,因为每次都是很纠结的去改这个bug,特别的烦人,这个bug也是使得我纠结了好久的,那个星期五自己搞了几个小时都没有解决下,之后星期一来百度Google ...
 - 【BZOJ2440】完全平方数 [莫比乌斯函数]
			
完全平方数 Time Limit: 10 Sec Memory Limit: 128 MB[Submit][Status][Discuss] Description 小X自幼就很喜欢数. 但奇怪的是 ...
 - 51nod 1020 逆序排列——dp
			
在一个排列中,如果一对数的前后位置与大小顺序相反,即前面的数大于后面的数,那么它们就称为一个逆序.一个排列中逆序的总数就称为这个排列的逆序数. 如2 4 3 1中,2 1,4 3,4 1,3 1是逆序 ...
 - WScript.Shell对象的 run()和exec()函数使用详解
			
WScript.Shell对象的 run()和exec()函数使用详解 http://blog.sina.com.cn/s/blog_6e14a2050102v47g.html vbScript ...
 - Python Requests 小技巧总结
			
关于 Python Requests ,在使用中,总结了一些小技巧把,分享下. 1:保持请求之间的Cookies,我们可以这样做. import requests self.session = req ...
 - JSOI2016酱油记
			
高一,第一次参加NOIP. 后悔初中没有报过名...唉,后悔也来不及了. 不知道自己一个暑假干了什么...算法没学多少,脑子倒是越来越不好使了. 过了初赛,数周后一脸茫(meng)然(bi)地去考场. ...
 - 【Android开发日记】之入门篇(十四)——Button控件+自定义Button控件
			
好久不见,又是一个新的学期开始了,为什么我感觉好惆怅啊!这一周也发生了不少事情,节假日放了三天的假(好久没有这么悠闲过了),实习公司那边被组长半强制性的要求去解决一个后台登陆的问题,结果就是把 ...