BZOJ3631:[JLOI2014]松鼠的新家——题解
http://www.lydsy.com/JudgeOnline/problem.php?id=3631
https://www.luogu.org/problemnew/show/P3258
松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的。天哪,他居然真的住在”树“上。
松鼠想邀请小熊维尼前来参观,并且还指定一份参观指南,他希望维尼能够按照他的指南顺序,先去a1,再去a2,......,最后到an,去参观新家。可是这样会导致维尼重复走很多房间,懒惰的维尼不停地推辞。可是松鼠告诉他,每走到一个房间,他就可以从房间拿一块糖果吃。
维尼是个馋家伙,立马就答应了。现在松鼠希望知道为了保证维尼有糖果吃,他需要在每一个房间各放至少多少个糖果。
因为松鼠参观指南上的最后一个房间an是餐厅,餐厅里他准备了丰盛的大餐,所以当维尼在参观的最后到达餐厅时就不需要再拿糖果吃了。
(强烈吐槽一下,这数据3e5压根出题人就不需要让你写差分干啥吃力不讨好呢?)
显然对于每个(a[i],a[i+1])树链剖分维护+1,最后a[1]--,a[n]--。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int N=3e5+;
inline int read(){
int X=,w=;char ch=;
while(ch<''||ch>''){w|=ch=='-';ch=getchar();}
while(ch>=''&&ch<='')X=(X<<)+(X<<)+(ch^),ch=getchar();
return w?-X:X;
}
struct node{
int to,nxt;
}edge[*N];
int head[N],q[N],cnt,tot,n;
inline void add(int u,int v){
edge[++cnt].to=v;edge[cnt].nxt=head[u];head[u]=cnt;
}
int fa[N],son[N],size[N],dep[N],idx[N],pos[N],top[N];
int sum[*N],lazy[*N];
void dfs1(int u){
size[u]=;
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].to;
if(v==fa[u])continue;
fa[v]=u;dep[v]=dep[u]+;
dfs1(v);
size[u]+=size[v];
if(!son[u]||size[son[u]]<size[v])son[u]=v;
}
}
void dfs2(int u,int anc){
pos[u]=++tot;
idx[tot]=u;
top[u]=anc;
if(!son[u])return;
dfs2(son[u],anc);
for(int i=head[u];i;i=edge[i].nxt){
int v=edge[i].to;
if(v==fa[u]||v==son[u])continue;
dfs2(v,v);
}
}
void init(){
dep[]=;
dfs1();
dfs2(,);
}
void push(int a,int l,int r){
int mid=(l+r)>>;
if(lazy[a]){
lazy[a*]+=lazy[a];
lazy[a*+]+=lazy[a];
sum[a*]+=(mid-l+)*lazy[a];
sum[a*+]+=(r-mid)*lazy[a];
lazy[a]=;
}
}
int query(int a,int l,int r,int l1,int r1){
if(r1<l||r<l1)return ;
if(l1<=l&&r<=r1)return sum[a];
int mid=(l+r)>>;
push(a,l,r);
return query(a*,l,mid,l1,r1)+query(a*+,mid+,r,l1,r1);
}
void modify(int a,int l,int r,int l1,int r1,int p){
if(r1<l||r<l1)return;
if(l1<=l&&r<=r1){
sum[a]+=(r-l+)*p;
lazy[a]+=p;
return;
}
int mid=(l+r)>>;
push(a,l,r);
modify(a*,l,mid,l1,r1,p);
modify(a*+,mid+,r,l1,r1,p);
sum[a]=sum[a*]+sum[a*+];
}
void pathmodify(int u,int v,int c){
while(top[u]!=top[v]){
if(dep[top[u]]<dep[top[v]])swap(u,v);
modify(,,n,pos[top[u]],pos[u],c);
u=fa[top[u]];
}
if(dep[u]>dep[v])swap(u,v);
modify(,,n,pos[u],pos[v],c);
return;
}
int main(){
n=read();
for(int i=;i<=n;i++)q[i]=read();
for(int i=;i<n;i++){
int u=read(),v=read();
add(u,v);add(v,u);
}
init();
modify(,,n,pos[q[]],pos[q[]],);
for(int i=;i<n;i++){
pathmodify(q[i],q[i+],);
modify(,,n,pos[q[i]],pos[q[i]],-);
}
modify(,,n,pos[q[n]],pos[q[n]],-);
for(int i=;i<=n;i++){
printf("%d\n",query(,,n,pos[i],pos[i]));
}
return ;
}
+++++++++++++++++++++++++++++++++++++++++++
+本文作者:luyouqi233。 +
+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+
+++++++++++++++++++++++++++++++++++++++++++
BZOJ3631:[JLOI2014]松鼠的新家——题解的更多相关文章
- BZOJ3631[JLOI2014]松鼠的新家 题解
题目大意: 给你一棵树,要从编号为a[1]的节点走到编号为a[2]的节点再走到编号为a[3]的节点……一直走到编号为a[n]的节点.问每个节点最少访问多少次. 思路: 将其进行轻重链剖分,则从a[i] ...
- [Bzoj3631][JLOI2014]松鼠的新家 (树上前缀和)
3631: [JLOI2014]松鼠的新家 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2350 Solved: 1212[Submit][Sta ...
- 洛谷 P3258 [JLOI2014]松鼠的新家 题解
P3258 [JLOI2014]松鼠的新家 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他 ...
- luoguP3258 [JLOI2014]松鼠的新家 题解(树上差分)
P3258 [JLOI2014]松鼠的新家 题目 树上差分:树上差分总结 #include<iostream> #include<cstdlib> #include<c ...
- BZOJ3631 [JLOI2014]松鼠的新家 【树上差分】
题目 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在"树"上.松鼠想 ...
- [BZOJ3631]:[JLOI2014]松鼠的新家(LCA+树上差分)
题目传送门 题目描述: 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在“树”上.松鼠想邀 ...
- P3258 [JLOI2014]松鼠的新家题解
题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有\(n\)个房间,并且有\(n-1\)根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在"树& ...
- [BZOJ3631][JLOI2014]松鼠的新家(树链剖分)
[BZOJ3631] 树剖模板题了, Code #include <cstdio> #include <algorithm> #define MID int mid=(l+r) ...
- bzoj3631: [JLOI2014]松鼠的新家(LCA+差分)
题目大意:一棵树,以一定顺序走完n个点,求每个点经过多少遍 可以树链剖分,也可以直接在树上做差分序列的标记 后者打起来更舒适一点.. 具体实现: 先求x,y的lca,且dep[x]<dep[y] ...
随机推荐
- MyEclipse相关用法介绍
MyEclipse相关用法介绍 ================================================================================ 编辑: ...
- CSP201312-2:ISBN号码
引言:CSP(http://www.cspro.org/lead/application/ccf/login.jsp)是由中国计算机学会(CCF)发起的"计算机职业资格认证"考试, ...
- 从零开始的Python学习Episode 1
一.输入与输出 1.输入 input("number:") num = input("number:") 下面一段可以把输入的信息存在num中. 注意:输入的信 ...
- springMVC使用拦截器检查用户登录
参考文章 编写拦截器类 package cultivate_web.interceptor; import javax.servlet.http.HttpServletRequest; import ...
- 【算法分析】如何理解快慢指针?判断linked list中是否有环、找到环的起始节点位置。以Leetcode 141. Linked List Cycle, 142. Linked List Cycle II 为例Python实现
引入 快慢指针经常用于链表(linked list)中环(Cycle)相关的问题.LeetCode中对应题目分别是: 141. Linked List Cycle 判断linked list中是否有环 ...
- leetcode个人题解——#24 Swap Nodes in Pairs
因为不太熟悉链表操作,所以解决方法烦了点,空间时间多有冗余. 代码中l,r分别是每一组的需要交换的左右指针,temp是下一组的头指针,用于交换后链接:res是交换后的l指针,用于本组交换后尾指针在下一 ...
- HADOOP docker(六):hive简易使用指南
前言1.hive简介1.1 hive组件与相应功能:1.2 hive的表类型1.3 分区表1.3 分隔符1.4 hive的数据存储2.数据类型2.1 基本数据类型2.1 复杂数据类型2.3 NULL3 ...
- object-oriented 第二次作业(2)
面向对象程序设计自学计划 由于我的英文实在是很差,所以我就没有去考虑看英文的课程视频.网络上的课程有很多,什么学校的也有,一开始我不知道该如何开始选择课程.感觉每个都还可以.后来在群里的看到别人推荐的 ...
- lintcode-138-子数组之和
138-子数组之和 给定一个整数数组,找到和为零的子数组.你的代码应该返回满足要求的子数组的起始位置和结束位置 注意事项 There is at least one subarray that it' ...
- MVC中验证码的实现(经常用,记录备用)
一.目录 1.多层架构+MVC+EF+AUTOFAC+AUTOMAPPER: 2.MVC中验证码的实现(经常用,记录备用) 3.Ligerui首页的快速搭建 二 正文 Ok,我们的验证码开始,这篇文章 ...