【题目链接】

http://acm.hdu.edu.cn/showproblem.php?pid=6162

【算法】

离线树剖

我们知道,u到v路径上权值为[A,B]的数的和 = u到v路径上权值小于等于B的数的和 - u到v路径上权值小于等于(A-1)的数的和

不妨将询问拆开,离线计算答案即可

【代码】

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + ; int i,n,m,u,v,now,timer,tot,cnt;
long long l,r;
int head[MAXN],size[MAXN],fa[MAXN],top[MAXN],
dep[MAXN],son[MAXN],dfn[MAXN];
long long ans[MAXN]; struct Edge
{
int to,nxt;
} e[MAXN<<];
struct info
{
int val,pos;
} a[MAXN];
struct Query
{
int u,v;
long long m;
int flag,id;
} q[MAXN<<]; struct SegmentTree
{
struct Node
{
int l,r;
long long sum;
} Tree[MAXN<<];
inline void build(int index,int l,int r)
{
int mid;
Tree[index] = (Node){l,r,};
if (l == r) return;
mid = (l + r) >> ;
build(index<<,l,mid);
build(index<<|,mid+,r);
}
inline void update(int index)
{
Tree[index].sum = Tree[index<<].sum + Tree[index<<|].sum;
}
inline void add(int index,int pos,long long val)
{
int mid;
if (Tree[index].l == Tree[index].r)
{
Tree[index].sum += val;
return;
}
mid = (Tree[index].l + Tree[index].r) >> ;
if (mid >= pos) add(index<<,pos,val);
else add(index<<|,pos,val);
update(index);
}
inline long long query(int index,int l,int r)
{
int mid;
if (Tree[index].l == l && Tree[index].r == r) return Tree[index].sum;
mid = (Tree[index].l + Tree[index].r) >> ;
if (mid >= r) return query(index<<,l,r);
else if (mid + <= l) return query(index<<|,l,r);
else return query(index<<,l,mid) + query(index<<|,mid+,r);
}
} T;
inline bool cmp1(info a,info b)
{
return a.val < b.val;
}
inline bool cmp2(Query a,Query b)
{
return a.m < b.m;
}
inline void add(int u,int v)
{
tot++;
e[tot] = (Edge){v,head[u]};
head[u] = tot;
}
inline void dfs1(int u)
{
int i,v;
size[u] = ;
for (i = head[u]; i; i = e[i].nxt)
{
v = e[i].to;
if (fa[u] != v)
{
fa[v] = u;
dep[v] = dep[u] + ;
dfs1(v);
size[u] += size[v];
if (size[v] > size[son[u]]) son[u] = v;
}
}
}
inline void dfs2(int u,int tp)
{
int i,v;
top[u] = tp;
dfn[u] = ++timer;
if (son[u]) dfs2(son[u],tp);
for (i = head[u]; i; i = e[i].nxt)
{
v = e[i].to;
if (fa[u] != v && son[u] != v) dfs2(v,v);
}
}
inline long long query(int u,int v)
{
int tu = top[u],
tv = top[v];
long long ret = ;
while (tu != tv)
{
if (dep[tu] > dep[tv])
{
swap(u,v);
swap(tu,tv);
}
ret += T.query(,dfn[tv],dfn[v]);
v = fa[tv]; tv = top[v];
}
if (dfn[u] > dfn[v]) swap(u,v);
ret += T.query(,dfn[u],dfn[v]);
return ret;
} int main()
{ while (scanf("%d%d",&n,&m) != EOF)
{
timer = ;
tot = ;
for (i = ; i <= n; i++)
{
head[i] = ;
son[i] = ;
}
cnt = ;
memset(ans,,sizeof(ans));
for (i = ; i <= n; i++)
{
scanf("%lld",&a[i].val);
a[i].pos = i;
}
for (i = ; i < n; i++)
{
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
dfs1();
dfs2(,);
T.build(,,timer);
for (i = ; i <= m; i++)
{
scanf("%d%d%lld%lld",&u,&v,&l,&r);
if (l > ) q[++cnt] = (Query){u,v,l-,,i};
q[++cnt] = (Query){u,v,r,,i};
}
sort(a+,a+n+,cmp1);
sort(q+,q+cnt+,cmp2);
now = ;
for (i = ; i <= cnt; i++)
{
while (now <= n && a[now].val <= q[i].m)
{
T.add(,dfn[a[now].pos],a[now].val);
now++;
}
if (q[i].flag == ) ans[q[i].id] -= query(q[i].u,q[i].v);
else ans[q[i].id] += query(q[i].u,q[i].v);
}
for (i = ; i < m; i++) printf("%lld ",ans[i]);
printf("%lld\n",ans[m]);
} return ; }

【HDU 6162】 Ch’s gift的更多相关文章

  1. 【 2017 Multi-University Training Contest - Team 9 && hdu 6162】Ch’s gift

    [链接]h在这里写链接 [题意] 给你一棵树,每个节点上都有一个权值. 然后给你m个询问,每个询问(x,y,a,b); 表示询问x->y这条路径上权值在[a,b]范围内的节点的权值和. [题解] ...

  2. 【HDU 2196】 Computer(树的直径)

    [HDU 2196] Computer(树的直径) 题链http://acm.hdu.edu.cn/showproblem.php?pid=2196 这题可以用树形DP解决,自然也可以用最直观的方法解 ...

  3. 【HDU 2196】 Computer (树形DP)

    [HDU 2196] Computer 题链http://acm.hdu.edu.cn/showproblem.php?pid=2196 刘汝佳<算法竞赛入门经典>P282页留下了这个问题 ...

  4. 【数位dp】【HDU 3555】【HDU 2089】数位DP入门题

    [HDU  3555]原题直通车: 代码: // 31MS 900K 909 B G++ #include<iostream> #include<cstdio> #includ ...

  5. 【HDU 5647】DZY Loves Connecting(树DP)

    pid=5647">[HDU 5647]DZY Loves Connecting(树DP) DZY Loves Connecting Time Limit: 4000/2000 MS ...

  6. -【线性基】【BZOJ 2460】【BZOJ 2115】【HDU 3949】

    [把三道我做过的线性基题目放在一起总结一下,代码都挺简单,主要就是贪心思想和异或的高斯消元] [然后把网上的讲解归纳一下] 1.线性基: 若干数的线性基是一组数a1,a2,a3...an,其中ax的最 ...

  7. 【HDU 5145】 NPY and girls(组合+莫队)

    pid=5145">[HDU 5145] NPY and girls(组合+莫队) NPY and girls Time Limit: 8000/4000 MS (Java/Other ...

  8. 【hdu 1043】Eight

    [题目链接]:http://acm.hdu.edu.cn/showproblem.php?pid=1043 [题意] 会给你很多组数据; 让你输出这组数据到目标状态的具体步骤; [题解] 从12345 ...

  9. 【HDU 3068】 最长回文

    [题目链接] http://acm.hdu.edu.cn/showproblem.php?pid=3068 [算法] Manacher算法求最长回文子串 [代码] #include<bits/s ...

随机推荐

  1. JS——arguments

    1.只在函数中使用 2.返回的是实参的数组 <script> getNum(1, 2);//(2) [1, 2, callee: ƒ, Symbol(Symbol.iterator): ƒ ...

  2. Replacing Threads with Dispatch Queues

    Replacing Threads with Dispatch Queues To understand how you might replace threads with dispatch que ...

  3. react 子组件调用父组件方法

    import React from 'react'import '../page1/header.css'import { Table } from 'antd'import Child from ' ...

  4. hdu 2084 数塔(简单dp)

    题目 简单dp //简单的dp #include<stdio.h> #include<string.h> #include<algorithm> using nam ...

  5. cogs——66. [HAOI2004模拟] 数列问题

    66. [HAOI2004模拟] 数列问题 本以为会TLE,可... dfs水题(很基础) #include<bits/stdc++.h> using namespace std; ],a ...

  6. Dinic当前弧优化 模板及教程

    在阅读本文前,建议先自学最大流的Ek算法. 引入 Ek的核心是执行bfs,一旦找到增广路就停下来进行增广.换言之,执行一遍BFS执行一遍DFS,这使得效率大大降低.于是我们可以考虑优化. 核心思路 在 ...

  7. HTML5本地存储——Web SQL Database与indexedDB

    虽然在HTML5 WebStorage介绍了html5本地存储的Local Storage和Session Storage,这两个是以键值对存储的解决方案,存储少量数据结构很有用,但是对于大量结构化数 ...

  8. CVE-2014-6271 漏洞告警

    原理:BASH除了可以将shell变量导出为环境变量,还可以将shell函数导出为环境变量!当前版本的bash通过以函数名作为环境变量名,以“(){”开头的字串作为环境变量的值来将函数定义导出为环境变 ...

  9. sql server的数据库个数、表个数及表的数据量统计

    sql server的数据库个数.表个数及表的数据量统计   --由于今天要监控数据,急需统计实例中1有多少库2库里有多少表3每个表有多少数据 --将写好的代码贴出来,用到如下的: --sysobje ...

  10. hdu 3657最大点权独立集变形(方格取数变形)

    /* 分奇偶为二部图,s与奇建图,t与偶建图,权值为当前数的值,如果遇到必取的权值置为inf. 奇偶建边为相邻的权值为2*(x&y):所有数的值-最小点全覆盖. 置为inf意为不能割掉.奇偶边 ...