缘起

【1】中我们学习了树上差分,并且a了一个裸的点差分. 现在继续树上差分~ 洛谷 P3258 [JLOI2014]松鼠的新家

分析

题目描述
松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,
且俩个房间之间的路线都是唯一的。天哪,他居然真的住在”树“上。松鼠想邀请小熊维尼前来参观,并且还指定一份参观指南,他希望维尼能够按照他的指南顺序,先去a1,再去
a2,......,最后到an,去参观新家。可是这样会导致维尼重复走很多房间,懒惰的维尼不停地推辞。可是松鼠告
诉他,每走到一个房间,他就可以从房间拿一块糖果吃。维尼是个馋家伙,立马就答应了。现在松鼠希望知道为了保证维尼有糖果吃,他需要在每一个房间各放至少多少个糖果。因为松鼠参观指南上的最后一个房间an是餐厅,餐厅里他准备了丰盛的大餐,所以当维尼在参观的最后到达餐厅时就不需要再拿糖果吃了。输入格式
第一行一个整数n,表示房间个数第二行n个整数,依次描述a1-an接下来n-1行,每行两个整数x,y,表示标号x和y的两个房间之间有树枝相连。输出格式
一共n行,第i行输出标号为i的房间至少需要放多少个糖果,才能让维尼有糖果吃。输入输出样例
输入 #1复制
5
1 4 5 3 2
1 2
2 4
2 3
4 5
输出 #1复制
1
2
1
2
1
说明/提示
2<= n <=300000

裸的点差分.

显然,小熊维尼的路线是 a1—a2、a2—a3、…a_{n-1}–an, 这些都是树上路径. 树上路径会造成一些树上节点的覆盖. 只需差分完毕之后dfs一波即可~ 但是注意,an这个点不需要放置糖果的意思是最后到达an的时候不需要吃糖果了,但是中途其他边可能路过an, 还是要放糖果的~ 所以最后 b[an]-- 即可. 但是从ai(i>1)到a\_{i+1} a[i]是不需要再放糖果的. 所以只要i不等于a[1](特别的, an 就不等于a[1]), 最后dfs完了之后就要自减1, 只是an和其他a[2,…,n-1]自减的原因不一样, an是因为最后不需要准备糖果,而a[i= 2,…,n-1]自减1是因为从ai出发不再需要放糖果.

//#include "stdafx.h"
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
//#define LOCAL
const int maxn = 3e5+5, maxl = 21;
int n, a[maxn], cnt, head[maxn], fa[maxn][maxl], dep[maxn], b[maxn];
bool v[maxn];
struct Arc
{int from, to, nxt;
}g[maxn << 1];void addarc(int from, int to)
{g[cnt].from = from, g[cnt].to = to, g[cnt].nxt = head[from];head[from] = cnt++;
}void dfs(int cur)
{v[cur] = true;for (int h = head[cur], to; ~h; h = g[h].nxt){to = g[h].to;if (v[to]){continue;}fa[to][0] = cur;dep[to] = dep[cur] + 1;dfs(to);}
}int lca(int x, int y)
{if (dep[x] > dep[y]){swap(x, y);}for (int j = maxl - 1; ~j; j--){if (dep[fa[y][j]] >= dep[x]){y = fa[y][j];}}if (x == y){return x;}for (int j = maxl - 1; ~j; j--){if (fa[x][j] ^ fa[y][j]){x = fa[x][j];y = fa[y][j];}}return fa[x][0];
}void cf(int x, int y)
{int a = lca(x, y);++b[x];++b[y];--b[a];--b[fa[a][0]];
}void dfs1(int cur)
{v[cur] = true;for (int h = head[cur], to; ~h; h = g[h].nxt){to = g[h].to;if (v[to]){continue;}dfs1(to);b[cur] += b[to];}
}int main()
{
#ifdef LOCALfreopen("d:\\data.in","r",stdin);
//  freopen("d:\\my.out", "w", stdout);
#endifmemset(head, -1, sizeof(head));scanf("%d", &n);for (int i = 1; i<=n; i++){scanf("%d", a + i);}int x, y;for (int i = 1;i < n; i++){scanf("%d%d", &x, &y);addarc(x, y);addarc(y, x);}dep[1] = 1;dfs(1);for (int j = 1, pa; j < maxl; j++){for (int i = 1; i <= n; i++){pa = fa[i][j - 1];fa[i][j] = fa[pa][j - 1];}}for (int i = 1; i < n; i++){x = a[i];y = a[i + 1];cf(x, y);}memset(v, 0, sizeof(v));dfs1(1);for (int i = 1; i <= n; i++){if (i ^ a[1]){--b[i];}printf("%d\n", b[i]);}return 0;
}

ac情况

所属题目
P3258 [JLOI2014]松鼠的新家
评测状态
Accepted
评测分数
100
编程语言
C++
代码长度
1.96KB
用时
934ms
内存
43.81MB

参考

【1】https://blog.csdn.net/anfengliuzhiwu/article/details/104434740

洛谷 P3258 [JLOI2014]松鼠的新家 树上差分相关推荐

  1. 洛谷 P3258 [JLOI2014]松鼠的新家 解题报告

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

  2. 洛谷 P3258 [JLOI2014]松鼠的新家

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

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

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

  4. 洛谷 P3258 [JLOI2014]松鼠的新家(树链剖分)

    题目要求熟练掌握树剖的概念,以及确定线段树的标号,题目应该不算难 这 n 个点之间,每两点之间都加 1 ,这样只有最后一个点和第一个点没有做多余的操作,题目还要求最后一次到达终点时不用再拿糖果,所以除 ...

  5. 【LOJ#2236】【洛谷P3258】松鼠的新家【LCA】【树上差分】

    题目大意: 题目链接: 洛谷:https://www.luogu.org/problem/P3258 LOJ:https://loj.ac/problem/2236 给出一棵树以及 n n n个点走的 ...

  6. 【洛谷P3258】松鼠的新家

    很好的一道题 LCA+树上前缀和 sum数组是前缀和数组, 分类讨论一下, 1.访问到一个点p1,若下一个点p2需要往儿子下面找的话,那么lca就是这个点p1,则sum[p1]--; sum[p2]+ ...

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

    P3258 [JLOI2014] 松鼠的新家 题解 洛谷 P3258 题目 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有 nnn 个房间,并且有 nnn−1 根树枝连接,每个房间都可以相互到达,且 ...

  8. P3258 [JLOI2014]松鼠的新家

    文章目录 题意: 题解: 树上差分 代码: 树链剖分 代码: P3258 [JLOI2014]松鼠的新家 题意: n个点,n-1条边,给出每个点的拜访顺序,问每个点经过几次(最后一次移动不算拜访) 题 ...

  9. P3258[JLOI2014]松鼠的新家(LCA 树上差分)

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

最新文章

  1. 分组卷积新进展,全自动学习的分组有哪些经典模型?
  2. JS模块化写法(转)
  3. Qt中QtTableWidget的使用
  4. long转时间 unity_Unity3D如何获取时间戳或北京时间
  5. 如何自动完成登录 SAP BTP workflow(工作流) 管理应用 Launchpad 所需的设置
  6. Java IO/NIO教程
  7. 云栖大会 | 释放计算弹性,阿里云做了很多
  8. kdump需要开启吗_iPhone全新黑科技!用嘴玩手机!你会玩吗?
  9. Linux基础命令---ziinfo
  10. 常用的字符串对象方法
  11. 计算机在医疗领域的发展未来,5G医疗在人工智能领域未来的发展
  12. 深度:余额宝技术架构及演进
  13. 一键识别图片中的表格数据,并转为Excel
  14. android数据格式化,手机格式化了?教你找回安卓手机数据
  15. python画彩虹圈_javascript – 如何使用HTML5画布生成彩虹圈?
  16. 计步器 c语言,ADXL345单片机计步器程序
  17. Golang sqlx 使用 Where in 解决办法
  18. 使用手机调试Android软件
  19. Python从Word/PPT/PDF中抽取图片
  20. 开源云服务器集群管理系统,#分享# Nano - 免费、开源基于CentOS/KVM虚拟化管理系统...

热门文章

  1. 使用sklearn库学习线性回归(一)
  2. 打开浏览器的同时会在主页外同时打开芒果TV,抖音等网站
  3. 常见面试题整理--操作系统篇
  4. 在 CSDN 博客 100 天技术日更的 Flag,我做到了!
  5. Android Studio底部导航
  6. docker 国内镜像设置
  7. SLAM综述论文:Past, Present, and Future of SLAM: Towards the Robust-Perception Age
  8. 苹果手机来电归属地_工信部:手机号归属地不会取消、否则增大诈骗风险-工信部,手机号,归属地,诈骗 ——快科技(驱动之家旗下媒体)-...
  9. SQL SERVER 查询、删除重复数据
  10. 影视剧中的武汉取景地,你去过几个?