UOJ261 【NOIP2016】天天爱跑步 LCA+动态开点线段树
UOJ261 【NOIP2016】天天爱跑步
Description
Input
Output
输出1行N 个整数,第个整数表示结点的观察员可以观察到多少人。
Sample Input
2 3
1 2
1 4
4 5
4 6
0 2 5 1 2 3
1 5
1 3
2 6
Sample Output
HINT
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define MAXN 300001
#define MAXM 10000001
using namespace std;
int n, m, w[MAXN], s[MAXN], t[MAXN], lca[MAXN], ans[MAXN];
int tot_e, to[2 * MAXN], nxt[2 * MAXN], pre[MAXN];
void add(int u, int v) { tot_e++, to[tot_e] = v, nxt[tot_e] = pre[u], pre[u] = tot_e; }
int deep[MAXN], fa[MAXN], son[MAXN], size[MAXN];
void dfs(int u, int f, int dep) {
fa[u] = f;
deep[u] = dep;
size[u] = 1;
for (int i = pre[u]; i; i = nxt[i]) {
int v = to[i];
if (v == f)
continue;
dfs(v, u, dep + 1);
size[u] += size[v];
if (size[v] > size[son[u]])
son[u] = v;
}
}
int top[MAXN], dfs_in[MAXN], dfs_out[MAXN], rk[MAXN], dfs_order = 0;
void DFS(int u, int top_chain) {
top[u] = top_chain;
dfs_in[u] = ++dfs_order;
rk[dfs_order] = u;
if (!son[u]) {
dfs_out[u] = dfs_order;
return;
}
DFS(son[u], top_chain);
for (int i = pre[u]; i; i = nxt[i]) {
int v = to[i];
if (v != son[u] && v != fa[u])
DFS(v, v);
}
dfs_out[u] = dfs_order;
}
int LCA(int x, int y) {
while (top[x] != top[y]) {
if (deep[top[x]] < deep[top[y]])
swap(x, y);
x = fa[top[x]];
}
return deep[x] < deep[y] ? x : y;
}
int tot_root = 0, ls[MAXM], rs[MAXM], sum[MAXM], root[MAXM];
void update(int &now, int l, int r, int pos, int val) {
if (!pos)
return;
if (!now)
now = ++tot_root;
sum[now] += val;
if (l == r)
return;
int mid = (l + r) >> 1;
if (pos <= mid)
update(ls[now], l, mid, pos, val);
else
update(rs[now], mid + 1, r, pos, val);
}
int query(int rt, int L, int R, int l, int r) { //[l,r]:目标区间,[L,R]:总区间
if (!rt)
return 0;
if (L == l && r == R)
return sum[rt];
int mid = (L + R) >> 1;
if (r <= mid)
return query(ls[rt], L, mid, l, r);
else if (l > mid)
return query(rs[rt], mid + 1, R, l, r);
else
return query(ls[rt], L, mid, l, mid) + query(rs[rt], mid + 1, R, mid + 1, r);
}
int main() {
scanf("%d%d", &n, &m);
for (int i = 1, u, v; i < n; i++) {
scanf("%d%d", &u, &v);
add(u, v), add(v, u);
}
for (int i = 1; i <= n; i++) scanf("%d", &w[i]);
dfs(1, 0, 1);
DFS(1, 0);
for (int i = 1; i <= m; i++) {
scanf("%d%d", &s[i], &t[i]);
lca[i] = LCA(s[i], t[i]);
}
for (int i = 1; i <= m; i++) {
update(root[deep[s[i]]], 1, n, dfs_in[s[i]], 1);
update(root[deep[s[i]]], 1, n, dfs_in[fa[lca[i]]], -1);
}
for (int i = 1; i <= n; i++)
ans[i] = query(root[deep[i] + w[i]], 1, n, dfs_in[i], dfs_out[i]);
tot_root = 0;
memset(ls, 0, sizeof(ls));
memset(rs, 0, sizeof(rs));
memset(sum, 0, sizeof(sum));
memset(root, 0, sizeof(root));
for (int i = 1; i <= m; i++) {
update(root[deep[s[i]] - 2 * deep[lca[i]] + 2 * n], 1, n, dfs_in[t[i]], 1);
update(root[deep[s[i]] - 2 * deep[lca[i]] + 2 * n], 1, n, dfs_in[lca[i]], -1);
}
for (int i = 1; i <= n; i++) ans[i] += query(root[w[i] - deep[i] + 2 * n], 1, n, dfs_in[i], dfs_out[i]);
for (int i = 1; i <= n; i++) printf("%d ", ans[i]);
puts("");
return 0;
}
UOJ261 【NOIP2016】天天爱跑步 LCA+动态开点线段树的更多相关文章
- [Vani有约会]雨天的尾巴——树上差分+动态开点线段树合并
题目描述 首先村落里的一共有n座房屋,并形成一个树状结构.然后救济粮分m次发放,每次选择两个房屋(x,y),然后对于x到y的路径上(含x和y)每座房子里发放一袋z类型的救济粮. 然后深绘里想知道,当所 ...
- LG4556 [Vani有约会]雨天的尾巴 动态开点线段树+线段树合并
问题描述 LG4556 题解 对于每一个结点,建立一棵动态开点线段树. 然后自低向上合并线段树. 同时维护整个值域的最大值和最大值位置. \(\mathrm{Code}\) #include<b ...
- [ZJOI2019]语言(树链剖分+动态开点线段树+启发式合并)
首先,对于从每个点出发的路径,答案一定是过这个点的路径所覆盖的点数.然后可以做树上差分,对每个点记录路径产生总贡献,然后做一个树剖维护,对每个点维护一个动态开点线段树.最后再从根节点开始做一遍dfs, ...
- [2016湖南长沙培训Day4][前鬼后鬼的守护 chen] (动态开点线段树+中位数 or 动规 or 贪心+堆优化)
题目大意 给定一个长度为n的正整数序列,令修改一个数的代价为修改前后两个数的绝对值之差,求用最小代价将序列转换为不减序列. 其中,n满足小于500000,序列中的正整数小于10^9 题解(引自mzx神 ...
- [bzoj 3531][SDOI2014]旅行(树链剖分+动态开点线段树)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3531 分析: 对于每个颜色(颜色<=10^5)都建立一颗线段树 什么!那么不是M ...
- 【BZOJ-4636】蒟蒻的数列 动态开点线段树 ||(离散化) + 标记永久化
4636: 蒟蒻的数列 Time Limit: 30 Sec Memory Limit: 256 MBSubmit: 247 Solved: 113[Submit][Status][Discuss ...
- codeforces 893F - Physical Education Lessons 动态开点线段树合并
https://codeforces.com/contest/893/problem/F 题意: 给一个有根树, 多次查询,每次查询对于$x$i点的子树中,距离$x$小于等于$k$的所有点中权值最小的 ...
- codeforces 915E - Physical Education Lessons 动态开点线段树
题意: 最大$10^9$的区间, $3*10^5$次区间修改,每次操作后求整个区间的和 题解: 裸的动态开点线段树,计算清楚数据范围是关键... 经过尝试 $2*10^7$会$MLE$ $10^7$会 ...
- CF915E Physical Education Lessons 动态开点线段树
题目链接 CF915E Physical Education Lessons 题解 动态开点线段树 代码 /* 动态开点线段树 */ #include<cstdio> #include&l ...
随机推荐
- 爬虫-Requests 使用入门
requests 的底层实现其实就是 urllib json在线解析工具 ---------------------------------------------- Linux alias命令用于设 ...
- 使用OxyPlot在WPF中创建图表
目录(?)[+] Using Nuget 包括OxyPlot在你的应用程序的最简单方法是使用NuGet包管理器在Visual Studio 运行 Visual Studio并开始创建一个新的WPF项目 ...
- Spring MVC(十五)--SpringMVC国际化配置项
Spring MVC中,当DispatcherServlet初始化的时候,会解析一个LocaleResolver接口的实现类,这个实现类就是用来解析国际化的. 一.国际化解析器 Spring MVC中 ...
- JAVA工具包_BeanUtils
简介 大多数的java开发者通常在创建Java类的时候都会遵循JavaBean的命名模式,对类的属性生成getters方法和setters方法.通过调用相应的getXxx和setXxx方法,直接访问这 ...
- IO初步,字节输入流和字节输出流
字节输出流 OutputStream(基类,抽象) 特点:写任意的文件 方法:写出数据的方法:write write(int b) 写出1个字节 -128~127之间,写的是一个ASCLL码的值 wr ...
- Cefsharp实现快捷键功能
原文:Cefsharp实现快捷键功能 1 . 实现IKeyboardHandler接口 public class KeyBoardHander : IKeyboardHandler { public ...
- python基础语法(变量与数据类型)
python基础语法(变量与数据类型) 一.python变量 python中的变量不需要声明.每个变量在使用钱都需要赋值,变量赋值以后,该变量才会被创建 在python中,变量就是变量,它没有类型,我 ...
- 解决Eclipse建立Maven Web项目后找不到src/main/java资源文件夹的办法
问题如题,明细见下图: 解决方法: 在项目上右键选择properties,然后点击java build path,在Librarys下,编辑JRE System Library,选择workspace ...
- scoreboarding
Reference docs: https://en.wikipedia.org/wiki/Scoreboarding SSC_course_5_Scoreboard_ex.pdf 1, what i ...
- windows安装apache系统中无apache2服务解决方案
一直都是用WIN开发PHP,今天有用户反映SHUGUANG CMS在APACHE+PHP中不能正常运行,只好自己机器配置个环境测试(http://xz.8682222.com)遇到点小问题,搜索相关资 ...