HDU 6162 - Ch’s gift | 2017 ZJUT Multi-University Training 9
/*
HDU 6162 - Ch’s gift [ LCA,线段树 ] | 2017 ZJUT Multi-University Training 9
题意:
N节点的树,Q组询问
每次询问s,t两节点之间的路径上点权值在[a,b]之间的点权总和
分析:
求出每个询问的LCA,然后离线
按dfs顺序更新树状数组,即某点处树状数组中存的值为其所有祖先节点的值
每个点处对答案的贡献为:
当其为第 i 个 lca 时, ans[i] -= 2 * query(a,b) , 再特判该节点
当其为第 i 个 s,t 时, ans[i] += query(a,b)
*/
#include <bits/stdc++.h>
using namespace std;
#define LL long long
const int N = 1e5+5;
typedef pair<int, int> P;
vector<int> G[N];//存边
vector<P> QQ[N];
int a[N], b[N*4], cnt, n, Q;
struct Query {
int s, t, lca, a, b;
}q[N];
void addedge(int u, int v) {
G[u].push_back(v);
}
namespace LCA {
struct Query {
int v, q;
}; vector <Query> query[N];//存每个点的询问
int ans[N], f[N], vis[N];
int sf(int x) {
return x == f[x] ? x : f[x] = sf(f[x]);
}
void init() {
memset(ans, -1, sizeof(ans));
for (int i = 0; i < N; i++) {
vis[i] = 0; f[i] = i; query[i].clear();
}
}
void adq(int u, int v, int id) {//添加询问
query[u].push_back(Query{v, id});
query[v].push_back(Query{u, id});
}
void LCA(int u) {
f[u] = u, vis[u] = 1;
for (auto& x : query[u]) {
if (vis[x.v] && ans[x.q] == -1)
ans[x.q] = sf(x.v);
}
for (auto& v : G[u]) {
if (vis[v]) continue;
LCA(v);
f[v] = u;
}
}
}
void init2()
{
cnt = 0;
for (int i = 1; i <= n; i++) b[++cnt] = a[i];
for (int i = 1; i <= Q; i++)
{
b[++cnt] = q[i].a;
b[++cnt] = q[i].b;
}
sort(b+1, b+cnt+1);
cnt = unique(b+1, b+cnt+1) - (b+1);
for (int i = 1; i <= n; i++)
a[i] = lower_bound(b+1, b+cnt+1, a[i]) - b;
for (int i = 1; i <= Q; i++)
{
q[i].a = lower_bound(b+1, b+cnt+1, q[i].a) - b;
q[i].b = lower_bound(b+1, b+cnt+1, q[i].b) - b;
}
}
LL ans[N], c[N<<4];
void modify(int x, LL num){
while (x <= cnt) c[x] += num, x += x&-x;
}
LL sum(int x) {
LL s = 0;
while (x) s += c[x], x -= x&-x;
return s;
}
void init()
{
memset(c, 0, sizeof(c));
for (int i = 0; i < N; i++) G[i].clear();
for (int i = 0; i < N; i++) QQ[i].clear();
memset(ans, 0, sizeof(ans));
}
void dfs(int u, int pre)
{
modify(a[u], b[a[u]]);
LL tmp;
for (auto & qq : QQ[u])
{
tmp = sum(q[qq.first].b) - sum(q[qq.first].a-1);
if (qq.second == -1)
{
ans[qq.first] -= 2*tmp;
if (a[u] >= q[qq.first].a && a[u] <= q[qq.first].b)
ans[qq.first] += b[a[u]];
}
else
{
ans[qq.first] += tmp;
}
}
for (auto&v: G[u])
{
if (v == pre) continue;
dfs(v, u);
}
modify(a[u], -b[a[u]]);
}
int main()
{
int u, v;
while (~scanf("%d%d", &n, &Q))
{
init();
for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
for (int i = 1; i < n; i++)
{
scanf("%d%d", &u, &v);
addedge(u, v); addedge(v, u);
}
for (int i = 1; i <= Q; i++)
scanf("%d%d%d%d", &q[i].s, &q[i].t, &q[i].a, &q[i].b);
init2();
LCA::init();
for (int i = 1; i <= Q; i++) LCA::adq(q[i].s, q[i].t, i);
LCA::LCA(1);
for (int i = 1; i <= Q; i++)
{
q[i].lca = LCA::ans[i];
QQ[q[i].lca].push_back(P(i, -1));
QQ[q[i].s].push_back(P(i, 1));
QQ[q[i].t].push_back(P(i, 1));
}
dfs(1, 1);
for (int i = 1; i < Q; i++) printf("%lld ", ans[i]);
printf("%lld\n", ans[Q]);
}
}
HDU 6162 - Ch’s gift | 2017 ZJUT Multi-University Training 9的更多相关文章
- 2017 Multi-University Training Contest - Team 9 1002&&HDU 6162 Ch’s gift【树链部分+线段树】
Ch’s gift Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total S ...
- HDU 6162 Ch’s gift (树剖 + 离线线段树)
Ch’s gift Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total S ...
- 2017多校第9场 HDU 6162 Ch’s gift 树剖加主席树
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6162 题意:给出一棵树的链接方法,每个点都有一个数字,询问U->V节点经过所有路径中l < ...
- HDU 6162 Ch’s gift
Mr. Cui is working off-campus and he misses his girl friend very much. After a whole night tossing a ...
- HDU 6162 Ch's gift(树链剖分+线段树)
题意: 已知树上的每个节点的值和节点之间的关系建成了一棵树,现在查询节点u到节点v的最短路径上的节点值在l到r之间的节点值的和. 思路: 用树链剖分将树映射到线段树上,线段树上维护3个值,max,mi ...
- HDU 6162 Ch’s gift (线段树+树链剖分)
题意:给定上一棵树,每个树的结点有一个权值,有 m 个询问,每次询问 s, t , a, b,问你从 s 到 t 这条路上,权值在 a 和 b 之间的和.(闭区间). 析:很明显的树链剖分,但是要用 ...
- HDU 6170 - Two strings | 2017 ZJUT Multi-University Training 9
/* HDU 6170 - Two strings [ DP ] | 2017 ZJUT Multi-University Training 9 题意: 定义*可以匹配任意长度,.可以匹配任意字符,问 ...
- L - Ch’s gift HDU - 6162
Ch’s gift Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total S ...
- HDU 6168 - Numbers | 2017 ZJUT Multi-University Training 9
/* HDU 6168 - Numbers [ 思维 ] | 2017 ZJUT Multi-University Training 9 题意: .... 分析: 全放入multiset 从小到大,慢 ...
随机推荐
- Java常用命令:jps、jstack、jmap、jstat(带有实例教程)
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u013310517/article/details/80990924 查看Java进程:jps ...
- Vue使用指南(一)
Vue Vue:前台框架 渐进式JavaScript框架 渐进式:vue可以控制页面的一个局部,vue也可以控制整个页面,vue也能控制整个前端项目 -- 根据项目需求,来决定vue控制项目的 ...
- 使用Spring Cloud OAuth2和JWT保护微服务
采用Spring Security AOuth2 和 JWT 的方式,避免每次请求都需要远程调度 Uaa 服务.采用Spring Security OAuth2 和 JWT 的方式,Uaa 服务只验证 ...
- 在论坛中出现的比较难的sql问题:20(触发器专题2)
原文:在论坛中出现的比较难的sql问题:20(触发器专题2) 最近,在论坛中,遇到了不少比较难的sql问题,虽然自己都能解决,但发现过几天后,就记不起来了,也忘记解决的方法了. 所以,觉得有必要记录下 ...
- LeetCode每日一练(1-3)
题目导航 1. 两数之和 2. 两数相加 3. 无重复字符的最长子串 1. 两数之和 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的 ...
- 微信小程序通讯录字母排序
微信小程序通讯录 字母排序效果: demo地址:https://github.com/PeachCoder/wechat-contacts
- java常见排序算法
今天去面试的时候又考了排序算法,排序这个东西,你以为你懂了,但是真正去写的时候才会发现好多细节自己都模棱两可,我写着写着就全都乱了,回来之后赶紧重新写一遍. (1)冒泡排序 public void b ...
- Python——初识网络爬虫(网页爬取)
网络爬虫(又称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本.另外一些不常使用的名字还有蚂蚁.自动索引.模拟程序或者蠕虫 ...
- Http 和 Socket 之间的恩爱情仇
前言 一些刚入门的小伙伴可能会用 Socket,也会用 OkHttp 或者 HttpUrlConnection 等一些 HTTP 客户端工具,这两个东西看着有点像可是又不太一样,到底是哪里不一样呢? ...
- QuickJS 快速入门 (QuickJS QuickStart)
1. QuickJS 快速入门 (QuickJS QuickStart) 1. QuickJS 快速入门 (QuickJS QuickStart) 1.1. 简介 1.2. 安装 1.3. 简单使用 ...