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]松鼠的新家——题解的更多相关文章

  1. BZOJ3631[JLOI2014]松鼠的新家 题解

    题目大意: 给你一棵树,要从编号为a[1]的节点走到编号为a[2]的节点再走到编号为a[3]的节点……一直走到编号为a[n]的节点.问每个节点最少访问多少次. 思路: 将其进行轻重链剖分,则从a[i] ...

  2. [Bzoj3631][JLOI2014]松鼠的新家 (树上前缀和)

    3631: [JLOI2014]松鼠的新家 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2350  Solved: 1212[Submit][Sta ...

  3. 洛谷 P3258 [JLOI2014]松鼠的新家 题解

    P3258 [JLOI2014]松鼠的新家 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他 ...

  4. luoguP3258 [JLOI2014]松鼠的新家 题解(树上差分)

    P3258 [JLOI2014]松鼠的新家  题目 树上差分:树上差分总结 #include<iostream> #include<cstdlib> #include<c ...

  5. BZOJ3631 [JLOI2014]松鼠的新家 【树上差分】

    题目 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在"树"上.松鼠想 ...

  6. [BZOJ3631]:[JLOI2014]松鼠的新家(LCA+树上差分)

    题目传送门 题目描述: 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在“树”上.松鼠想邀 ...

  7. P3258 [JLOI2014]松鼠的新家题解

    题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有\(n\)个房间,并且有\(n-1\)根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在"树& ...

  8. [BZOJ3631][JLOI2014]松鼠的新家(树链剖分)

    [BZOJ3631] 树剖模板题了, Code #include <cstdio> #include <algorithm> #define MID int mid=(l+r) ...

  9. bzoj3631: [JLOI2014]松鼠的新家(LCA+差分)

    题目大意:一棵树,以一定顺序走完n个点,求每个点经过多少遍 可以树链剖分,也可以直接在树上做差分序列的标记 后者打起来更舒适一点.. 具体实现: 先求x,y的lca,且dep[x]<dep[y] ...

随机推荐

  1. libevent学习五(Helper functions and types for Libevent)

    基础类型   #ifdef WIN32 #define evutil_socket_t intptr_t #else #define evutil_socket_t int #endif ev_ssi ...

  2. pip源设置 & pandas安装

    pip的官方源python.pypi.org貌似被墙,换用国内安装源 网上的设置方法都是基于Unix的,Windows下的设置略麻烦. 更新..\Lib\site-packages\pip下的cmdo ...

  3. NGUI组件整理总结

    一图流: 注意: private void RClickUI(Vector3 newPos) { this.gameObject.SetActive(true); this.transform.loc ...

  4. HDU - 6409:没有兄弟的舞会(数学+思维)

    链接:HDU - 6409:没有兄弟的舞会 题意: 题解: 求出最大的 l[i] 的最大值 L 和 r[i] 的最大值 R,那么 h 一定在 [L, R] 中.枚举每一个最大值,那么每一个区间的对于答 ...

  5. django 增删改查操作 数据库Mysql

    下面介绍一下django增删改查操作: 1.view.py # -*- coding: utf-8 -*-from __future__ import unicode_literalsfrom dja ...

  6. Scala学习笔记之Actor多线程与线程通信的简单例子

    题目:通过子线程读取每个文件,并统计单词数,将单词数返回给主线程相加得出总单词数 package review import scala.actors.{Actor, Future} import s ...

  7. 名人问题 算法解析与Python 实现 O(n) 复杂度 (以Leetcode 277. Find the Celebrity为例)

    1. 题目描述 Problem Description Leetcode 277. Find the Celebrity Suppose you are at a party with n peopl ...

  8. 前端整合MathjaxJS的配置笔记

    这篇文章是我给Pinghsu主题添加数学公式功能的一个小教程,包含我大量的官方文档阅读后的实践,跟着这篇配置教程走,你可以做到给任何一个需要数学公式的站点添加支持. 教程如标题所述是针对 Mathja ...

  9. DataSet转化为DataTable

    . DataTable dt = ds.Tables[]; . DataTable dt = dao.FillTables("GetOptions_DKI_City_HCPName" ...

  10. Asp.net之数组应用

    string[] abc=new string[8]{"1","2","3","4","1",&qu ...