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 ...
随机推荐
- Kunbernetes从私有仓库nexus拉取镜像
1.docker登陆认证 [root@master ~]# vim /etc/docker/daemon.json { "insecure-registries": [" ...
- Hibernate之Inverse的用法
在多的一端配置Inverse设置为true,来自动管理关系
- 出现不不能引java.util.Date包的情况
出现不不能引java.util.Date包的情况 那个时间段不能引,IDE的bug,等一会儿就好了 心得:很多时候没必要和bug死磕,因为真的不是你的问题.
- ThinkPHP 的缓存大概多久更新一次
ThinkPHP 的缓存大概多久更新一次可以自己设置: thinkPHP的缓存默认是文件缓存,保存在Runtime文件夹里面, 如果不设置过期时间,且不清除Runtime文件,就会一直存在. 如果设置 ...
- AtCoder ABC 129E Sum Equals Xor
题目链接:https://atcoder.jp/contests/abc129/tasks/abc129_e 题目大意 给定一个二进制表示的数 L,问有多少对自然数 (a, b) 满足 $a + b ...
- day 65 Django基础之django分页
Django基础之django分页 一.Django的内置分页器(paginator) view from django.shortcuts import render,HttpRespons ...
- 4_4.springboot之Web开发登录和拦截器
1.登录处理 1).禁用模板引擎的缓存 # 禁用缓存 spring.thymeleaf.cache=false 2).页面修改完用ctrl+f9:重新编译: LoginController @Cont ...
- Java开发系列-JSP
概述 JSP是java 服务器页面,它运行在服务器端,本质上就是一个serlvet,产生的java文件和class保留在tomcat的word目录下. JSP主要作用是将内容的生成与页面相分离. JS ...
- 关于Android 的网址
Android 官方API查询网址 https://developer.android.google.cn/ 第三方镜像Android API查询网址 (比官方浏览速度快一些,缺点现有API较低) h ...
- Codeforces 839D Winter is here
链接:CF839D 题目大意 给定一个数组大小为\(n(1\leq n\leq 200000)\)的数组\(a\),满足\(1\leq a_i \leq 1000000\). 选择其中任意\(len\ ...