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 ...
随机推荐
- Apache Flink 进阶(三):Checkpoint 原理解析与应用实践
大家好,今天我将跟大家分享一下 Flink 里面的 Checkpoint,共分为四个部分.首先讲一下 Checkpoint 与 state 的关系,然后介绍什么是 state,第三部分介绍如何在 Fl ...
- csp-s模拟99题解
题面:https://www.cnblogs.com/Juve/articles/11791219.html 上来先看T1,发现和之前做过的treap一样,是线段树维护单调栈,然后打了一个小时,然后它 ...
- 如何在CRichEditCtrl控件中直接读如RTF格式的文件(这个是通过流的方式来读取文件)
如何在CRichEditCtrl控件中直接读如RTF格式的文件 Inserting an RTF string using StreamIn ------------------------- ...
- PAT甲级——A1109 Group Photo【25】
Formation is very important when taking a group photo. Given the rules of forming K rows with Npeopl ...
- deployment资源
目的:用rc在滚动升级之后,会造成服务访问中孤单,于是k8s引入了deploymentziyuan 创建deployment vim k8s_deploy.yml apiVersion: extens ...
- Git初次使用,记录自己看
Git官网下载:https://git-scm.com/downloads 官网如果太慢,可以去这下载:http://www.wmzhe.com/soft-38801.html,注意选择如下图地址下载 ...
- Python自学--part1
概要 Python介绍 Python安装 Hello World程序 变量 字符编码 用户输入 pyc是个什么鬼? 数据类型初识 数据运算 表达式if ...else语句 表达式while 循环 表达 ...
- flexbox属性速览及常见布局实现
CSS3 弹性盒子(Flex Box)弹性盒子是即 CSS2 浮动布局后, CSS3 的一种新的布局模式. CSS3 弹性盒( Flexible Box 或 flexbox),是一种当页面需要适应不同 ...
- [WPF自定义控件库] 让Form在加载后自动获得焦点
原文:[WPF自定义控件库] 让Form在加载后自动获得焦点 1. 需求 加载后让第一个输入框或者焦点是个很基本的功能,典型的如"登录"对话框.一般来说"登录" ...
- 编写Map处理逻辑