/*
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的更多相关文章

  1. 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 ...

  2. HDU 6162 Ch’s gift (树剖 + 离线线段树)

    Ch’s gift Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total S ...

  3. 2017多校第9场 HDU 6162 Ch’s gift 树剖加主席树

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6162 题意:给出一棵树的链接方法,每个点都有一个数字,询问U->V节点经过所有路径中l < ...

  4. 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 ...

  5. HDU 6162 Ch's gift(树链剖分+线段树)

    题意: 已知树上的每个节点的值和节点之间的关系建成了一棵树,现在查询节点u到节点v的最短路径上的节点值在l到r之间的节点值的和. 思路: 用树链剖分将树映射到线段树上,线段树上维护3个值,max,mi ...

  6. HDU 6162 Ch’s gift (线段树+树链剖分)

    题意:给定上一棵树,每个树的结点有一个权值,有 m 个询问,每次询问 s, t ,  a, b,问你从 s 到 t 这条路上,权值在 a 和 b 之间的和.(闭区间). 析:很明显的树链剖分,但是要用 ...

  7. HDU 6170 - Two strings | 2017 ZJUT Multi-University Training 9

    /* HDU 6170 - Two strings [ DP ] | 2017 ZJUT Multi-University Training 9 题意: 定义*可以匹配任意长度,.可以匹配任意字符,问 ...

  8. 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 ...

  9. HDU 6168 - Numbers | 2017 ZJUT Multi-University Training 9

    /* HDU 6168 - Numbers [ 思维 ] | 2017 ZJUT Multi-University Training 9 题意: .... 分析: 全放入multiset 从小到大,慢 ...

随机推荐

  1. 介绍几款常用的在线API管理工具

    在项目开发过程中,总会涉及到接口文档的设计编写,之前使用的都是ms office工具,不够漂亮也不直观,变更频繁的话维护成本也更高,及时性也是大问题.基于这个背景,下面介绍几个常用的API管理工具,方 ...

  2. C++ 字符串处理类 ProcessString (包含常用字符串处理函数)

    ProcessString.h //Linux & C++11 #pragma once //包含系统头文件 #include <string> #include <sstr ...

  3. php面向对象之封装

    OOP三大特性:封装.继承和多态,简称封继态. 封装 类2使用关键字extends继承类1,之后,类1为类2的父类,简称父类,类2是类1的子类,简称子类.使用关键字new,实例化类1,得到对象1,对象 ...

  4. SAS学习笔记52 Excel导入后日期错乱

    读入Excel数据到SAS中,很小概率会遇到日期格式错乱,如:将Excel中的日期导入到SAS后就变成一个字符型的数字 在SAS中换算一下就可以更正

  5. thrift原理与架构

    是什么: 一个RPC框架.

  6. 怎样重启ssh服务

    尝试下面两个命令: service sshd restart systemctl restart sshd.service

  7. windows下mysql表名区分大小写

    windows下mysql默认是不区分大小写的,但是linux会区分大小写 如何让windows下mysql区分大小写呢? 修改 my.ini 里面的mysqld部分 #区分大小写 lower_cas ...

  8. JQuery 的优先级

    1.使用最新的jQuery版本 2.用对选择器.   2.1 jquery最快的选择器是ID选择器:来源于js的getElementById()方法 注释:需要选择多个元素,必然涉及到Dom遍历和循环 ...

  9. 【转载】C#中使用OrderBy和ThenBy等方法对List集合进行排序

    在C#的List操作中,针对List对象集合的排序我们可以使用OrderBy.OrderByDescending.ThenBy.ThenByDescending等方法按照特定的对象属性进行排序,其中O ...

  10. h5 点击ios键盘完成 出现键盘大小的白块

    document.addEventListener('focusout', function (e) { window.scrollTo() }) 源文件链接 https://blog.csdn.ne ...