「NOIP2016」天天爱跑步
传送门
Luogu
解题思路
树上差分+桶计数。
我们发现在一条路径上的点 \(i\) ,它可以观测到玩家的条件是:
- \(i \in (u \to LCA),dep_u=w_i+dep_i\)
- \(i \in (LCA \to v),dis(u,v)-dep_v=w_i-dep_i\)
所以我们就可以树上差分加桶计数实现,每次的答案就是对应桶的变化量。
细节注意事项
- 为了防止数组下标出现负数,可以统一加上一个数
参考代码
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <cctype>
#include <cmath>
#include <ctime>
#include <vector>
#define rg register
using namespace std;
template < typename T > inline void read(T& s) {
s = 0; int f = 0; char c = getchar();
while (!isdigit(c)) f |= (c == '-'), c = getchar();
while (isdigit(c)) s = s * 10 + (c ^ 48), c = getchar();
s = f ? -s : s;
}
const int _ = 300002;
int tot, head[_], nxt[_ << 1], ver[_ << 1];
inline void Add_edge(int u, int v)
{ nxt[++tot] = head[u], head[u] = tot, ver[tot] = v; }
int n, m, w[_], ans[_], tong[2][_ * 3];
int dep[_], fa[21][_];
struct node { int f, p, v; } ;
vector < node > vec[_];
inline void dfs(int u, int f) {
dep[u] = dep[f] + 1, fa[0][u] = f;
for (rg int i = 1; i <= 19; ++i)
fa[i][u] = fa[i - 1][fa[i - 1][u]];
for (rg int i = head[u]; i; i = nxt[i]) {
int v = ver[i]; if (v == f) continue;
dfs(v, u);
}
}
inline int LCA(int x, int y) {
if (dep[x] < dep[y]) swap(x, y);
for (rg int i = 19; ~i; --i)
if (dep[fa[i][x]] >= dep[y]) x = fa[i][x];
if (x == y) return x;
for (rg int i = 19; ~i; --i)
if (fa[i][x] != fa[i][y]) x = fa[i][x], y = fa[i][y];
return fa[0][x];
}
inline void diff(int s, int t) {
int lca = LCA(s, t), dis = dep[s] + dep[t] - 2 * dep[lca];
vec[s].push_back((node) { 0, dep[s] + _, 1 });
vec[lca].push_back((node) { 0, dep[s] + _, -1});
vec[t].push_back((node) { 1, dis - dep[t] + _, 1 });
vec[fa[0][lca]].push_back((node) { 1, dis - dep[t] + _, -1 });
}
inline void dfss(int u, int f) {
int tmp = tong[0][w[u] + dep[u] + _] + tong[1][w[u] - dep[u] + _];
for (rg int i = 0; i < (int) vec[u].size(); ++i)
tong[vec[u][i].f][vec[u][i].p] += vec[u][i].v;
for (rg int i = head[u]; i; i = nxt[i]) {
int v = ver[i]; if (v == f) continue;
dfss(v, u);
}
ans[u] = tong[0][w[u] + dep[u] + _] + tong[1][w[u] - dep[u] + _] - tmp;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in.in", "r", stdin);
freopen("out.out", "w", stdout);
#endif
read(n), read(m);
for (rg int u, v, i = 1; i < n; ++i)
read(u), read(v), Add_edge(u, v), Add_edge(v, u);
for (rg int i = 1; i <= n; ++i) read(w[i]);
dfs(1, 0);
for (rg int s, t, i = 1; i <= m; ++i) read(s), read(t), diff(s, t);
dfss(1, 0);
for (rg int i = 1; i <= n; ++i) printf("%d%c", ans[i], " \n"[i == n]);
return 0;
}
完结撒花 \(qwq\)
「NOIP2016」天天爱跑步的更多相关文章
- LOJ #2359. 「NOIP2016」天天爱跑步(倍增+线段树合并)
题意 LOJ #2359. 「NOIP2016」天天爱跑步 题解 考虑把一个玩家的路径 \((x, y)\) 拆成两条,一条是 \(x\) 到 \(lca\) ( \(x, y\) 最近公共祖先) 的 ...
- 「NOIP2016」天天爱跑步 题解
(声明:图片来源于网络) 「NOIP2016」天天爱跑步 题解 题目TP门 题目 题目描述 小c同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.<天天爱跑步>是 ...
- LOJ2359. 「NOIP2016」天天爱跑步【树上差分】
LINK 思路 首先发现如果对于一个节点,假设一个节点需要统计从字数内来的贡献 需要满足\(dep_u - dep_s = w_u\) 这个条件其实可以转化成\(dep_u - w_u = dep_s ...
- UOJ261 【NOIP2016】天天爱跑步 LCA+动态开点线段树
UOJ261 [NOIP2016]天天爱跑步 Description 小c同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.天天爱跑步是一个养成类游戏,需要玩家每天按时上线, ...
- UOJ261 【NOIP2016】天天爱跑步
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000作者博客:http://www.cnblogs.com/ljh2000-jump/转 ...
- 【NOIP2016】天天爱跑步
题目描述 小c同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.«天天爱跑步»是一个养成类游戏,需要玩家每天按时上线,完成打卡任务. 这个游戏的地图可以看作一一棵包含 个结点 ...
- 【NOIP2016】天天爱跑步(树上差分)
题意: 小c同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.?天天爱跑步?是一个养成类游戏,需要 玩家每天按时上线,完成打卡任务.这个游戏的地图可以看作一一棵包含 N个结点 ...
- NOIP2016(D1T2)天天爱跑步题解
首先声明这不是一篇算法独特的题解,仍然是"LCA+桶+树上差分",但这篇题解是为了让很多很多看了很多题解仍然看不懂的朋友们看懂的,其中就包括我,我也在努力地把解题的"思维 ...
- LOJ2362. 「NOIP2016」蚯蚓【单调队列】
LINK 思路 良心来说这题还挺思维的 我没看题解也不知道要这样维护 把每次斩断的点分别放进两个队列里面 因为要维护增长,所以可以让新进队的节点来一个负增长? 是不是就好了? 然后很容易发现因为在原始 ...
随机推荐
- USER 指定当前用户,希望以某个已经建立好的用户来运行某个服务进程,不要使用 su 或者 sudo,这些都需要比较麻烦的配置,而且在 TTY 缺失的环境下经常出错。建议使用 gosu
USER 指定当前用户 格式:USER <用户名>[:<用户组>] USER 指令和 WORKDIR 相似,都是改变环境状态并影响以后的层.WORKDIR 是改变工作目录,US ...
- POJ1797 Heavy Transportation (堆优化的Dijkstra变形)
Background Hugo Heavy is happy. After the breakdown of the Cargolifter project he can now expand bus ...
- Codeforces Round #608 (Div. 2) - D. Portals(贪心)
题意:你起初有一支军队,有$k$个士兵,现在有$n$座城堡,你若想占领第$i$座城堡,至少得有$a[i]$个士兵才能占领$($占领后士兵不会减少$)$,占领了第$i$座城堡后,你将得到$b[i]$个士 ...
- 后端——框架——持久层框架——Mybatis——《Mybatis从入门到精通》读书笔记——初篇
1.Mybatis知识点 框架的知识点大致可以分为三个部分 基础: 介绍编写增,删,改,查: 动态标签: config配置文件 Mapper配置文件 插件:常见的插件有三个 pageHelper:分页 ...
- 监控Tomcat状态!(重点)
方法一:开发JAVA监控页面 [root@localhost ~]# mkdir /usr/local/tomcat8/webapps/memtest/[root@localhost ~]# cd / ...
- 阿里云oss操作
参考网址 https://blog.csdn.net/qq_22764659/article/details/87969743
- CSS背景透明设置
style="margin-top:300px;background:rgba(255,255,255,这里设置小于1比如0.6这样); color:black;" style=& ...
- table 实现向下滑动首行冻结,向右滑动左列冻结
<html> <head> <meta charset="utf-8"> <title>测试</title> <M ...
- Tomcat认识
Tomcat目录结构: bin:存放启动和关闭的一些脚本 common:共享(部署在该服务器上的一些)jar包 conf:存放服务器的一些配置文件 webapps:部署文件 work:服务器运行时,产 ...
- loadrunner回放时弹出windows安全警告
在录制 https://www.baidu.com,回放时总是弹出安全警告. 处理方案:打开IE的internet选项-->隐私,设置成“接受所有Cookie”,如下图所示即可解决