3631: [JLOI2014]松鼠的新家


Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 2350  Solved: 1212
[Submit][Status][Discuss]

Description


松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的。天哪,他居然真的住在“树”上。松鼠想邀请小熊维尼前来参观,并且还指定一份参观指南,他希望维尼能够按照他的指南顺序,先去a1,再去a2,……,最后到an,去参观新家。
可是这样会导致维尼重复走很多房间,懒惰的维尼不听地推辞。可是松鼠告诉他,每走到一个房间,他就可以从房间拿一块糖果吃。维尼是个馋家伙,立马就答应了。
现在松鼠希望知道为了保证维尼有糖果吃,他需要在每一个房间各放至少多少个糖果。因为松鼠参观指南上的最后一个房间an是餐厅,餐厅里他准备了丰盛的大餐,所以当维尼在参观的最后到达餐厅时就不需要再拿糖果吃了。

Input


第一行一个整数n,表示房间个数
第二行n个整数,依次描述a1-an
接下来n-1行,每行两个整数x,y,表示标号x和y的两个房间之间有树枝相连。

Output


一共n行,第i行输出标号为i的房间至少需要放多少个糖果,才能让维尼有糖果吃。

Sample Input



Sample Output



HINT


2<= n <=300000

分析:


今天做了noip2015 day2 t3,发现这道省选题竟然是它的简化版。。。。。。。。

道理一样求树上前缀和,以第一个访问的为根,求出dfs序(每个点的st和en)和lca。

对于每一个访问的点u,和前一个点pre在前缀和数组里 +1,他们的lca -2.

这样对于除了根节点以外的所有点,他们的起始位置到结尾位置的和就为那条边经过的次数。(这个用前缀和O(n)处理,每次求一个点只用sum[en] - sum[st - 1]就可以了)。

对于每条边出现次数x,两端的点答案各加x/2,如果为奇数深度更深的那个点答案再加1

根节点最后要加一,最后位置要减1,其实比noip那道题还简单。。。。。

AC代码:


# include <iostream>
# include <cstdio>
# include <cstring>
# include <cstdlib>
# include <algorithm>
using namespace std;
const int N = 3e5 + ;
int head[N],cnt,n,lg,maxn;
int fa[N][],dep[N],vis[N];
struct Edge{
int to,next;
}edge[N << ];
void AddEdge(int u,int v){
Edge E = {v,head[u]};
edge[++cnt] = E;head[u] = cnt;
}
int st[N],en[N];
long long ans[N],sum[N];
void dfs(int u,int pre){
st[u] = ++cnt;
for(int i = head[u];i;i = edge[i].next){
int v = edge[i].to;
if(v == pre)continue;
fa[v][] = u;
dep[v] = dep[u] + ;
dfs(v,u);
}
maxn = max(maxn,dep[u]);
en[u] = cnt;
}
int lca(int x,int y){
if(dep[x] < dep[y])swap(x,y);
for(int i = lg;i >= ;i--){
if(dep[x] - ( << i) >= dep[y])x = fa[x][i];
}
for(int i = lg;i >= ;i--){
if((dep[x] - ( << i)) && fa[x][i] != fa[y][i]){
x = fa[x][i];
y = fa[y][i];
}
}
if(x != y)x = fa[x][];
return x;
}
int main(){
scanf("%d",&n);
int x,y,root;
for(int i = ;i <= n;i++){
scanf("%d",&vis[i]);
}
root = vis[];
for(int i = ;i < n;i++){
scanf("%d %d",&x,&y);
AddEdge(x,y);
AddEdge(y,x);
}
cnt = ;
dep[root] = maxn = ;
dfs(root,-);
int pre = root;
for(lg = ;( << lg) <= maxn;lg++);lg--;
for(int j = ;j <= lg;j++){
for(int i = ;i <= n;i++){
fa[i][j] = fa[fa[i][j - ]][j - ];
}
}
for(int i = ;i <= n;i++){
sum[st[vis[i]]]++;sum[st[pre]]++;
sum[st[lca(vis[i],pre)]] -= ;
pre = vis[i];
}
for(int i = ;i <= n;i++){
sum[i] += sum[i - ];
}
long long z;
for(int i = ;i <= n;i++){
z = sum[en[i]] - sum[st[i] - ];
if(z & 1LL){
ans[i]++;
}
ans[i] += z / 2LL;ans[fa[i][]] += z / 2LL;
}
ans[pre]--;ans[root]++;
for(int i = ;i <= n;i++){
printf("%lld\n",ans[i]);
}
}

[Bzoj3631][JLOI2014]松鼠的新家 (树上前缀和)的更多相关文章

  1. bzoj3631 [JLOI2014]松鼠的新家——树上差分

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3631 树上差分:注意路径的结尾被多算了一次,最后要减去(不能提前减). 代码如下: #inc ...

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

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

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

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

  4. BZOJ 3631: [JLOI2014]松鼠的新家 树上差分 + LCA

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

  5. bzoj3631: [JLOI2014]松鼠的新家(树上差分)

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=3631 题目大意:给定含有n个顶点的树,给定走遍整棵树顺序的序列a[1],a[2],a[3 ...

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

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

  7. BZOJ3631: [JLOI2014]松鼠的新家

    传送门 树上的差分优化,很简单的一道题,应该属于NOIP2015TGD2T3的子问题. //BZOJ 3631 //by Cydiater //2016.10.25 #include <iost ...

  8. bzoj3631[JLOI2014 松鼠的新家 倍增lca+差分

    裸的树上差分+倍增lca 每次从起点到终点左闭右开,这就有一个小技巧,要找到右端点向左端点走的第一步,然后差分就好了 #include<cstdio> #include<cstrin ...

  9. [JLOI2014]松鼠的新家 树上差分

    差分 一开始竟然想分情况讨论来差分,然后发现各自情况要分析, 就是为了解决中间节点重复计算的问题, 结果 最后一想,中间重复计算了一次,那我最后减掉不就好了么,,, 那这就是一道差分裸题了(这是唯一不 ...

随机推荐

  1. lavarel功能总结

    详细可参见笔记:laraval学习笔记(二) 路由 route 绑定模型,绑定参数 模版 blade .blade.php后缀,有laravel自己的模版语法 模型 model 如果用create创建 ...

  2. (C#)Xamarin.ios 发布到 App Store

    项目做到尾声了,IOS要发布,程序猿力Max来了. 不过就公司开发者账号就弄了一个月多,期间因为申请过D-U-N-S客服联系要公司资料时我们中途说取消了,后来再申请不知多少次了都没再回复... 给美国 ...

  3. ElasticSearch可视化工具 Kibana

    Kibana要和ElasticSearch 版本一致,默认的端口号是:5601

  4. sqlserver 数据库主外键关联错误

    话题引入: 在建立主外键关系时,系统提示表"table2"中的列与现有的主键或UNIQUE约束不匹配 原因: 数据库表中只有一个主键,这个主键可以是多个列共同组成.所以table2 ...

  5. expand - 把 tab 符转换为空格符

    总览 (SYNOPSIS) ../src/expand [OPTION]... [FILE]... 描述 (DESCRIPTION) 把 各文件 FILE 中的 tab 符 转换为 空格符, 然后 写 ...

  6. uva820 Internet Bandwidth

    就是模板... #include<cstdio> #include<cstring> #include<vector> #include<queue> ...

  7. QT_7_资源文件_对话框_QMessageBox_界面布局_常用控件

    资源文件 1.1. 将资源导入到项目下 1.2. 添加文件—>Qt -->Qt Resource File 1.3. 起名称 res ,生成res.qrc文件 1.4. 右键 open i ...

  8. 【lua实战摸索】在b.lua调用a.lua的函数

    需要掌握知识: lua table的使用(创建自己函数的表作为函数库) 普通函数的调用:tab.func(tab,参数) 等效于表中函数的调用tab:func(参数) 基本思路: 1.在相同目录下创建 ...

  9. docker部署xxl-job

    资源 xxl-job:1.9.1 docker:17.05.0-ce maven:3.5.0-jdk-8 tomcat:8.5.23.0 mysql:5.6.40 一.创建数据库 克隆项目到服务器下 ...

  10. Centos 7 编译nginx 1.14.0

    步骤一:下载nginx安装包 wget https://nginx.org/download/nginx-1.14.0.tar.gz 步骤二:安装nginx依赖包 yum install -y gcc ...