【题目链接】

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. BAT文件如何注释

    1.BAT文件中如何注释: 1.:: 注释内容(第一个冒号后也可以跟任何一个非字母数字的字符) 2.rem 注释内容(不能出现重定向符号和管道符号) 3.echo 注释内容(不能出现重定向符号和管道符 ...

  2. [Windows Server 2003] 安装SQL Server 2005

    ★ 欢迎来到[护卫神·V课堂],网站地址:http://v.huweishen.com★ 护卫神·V课堂 是护卫神旗下专业提供服务器教学视频的网站,每周更新视频.★ 本节我们将带领大家:安装SQL S ...

  3. (转) 基于Arcgis for Js的web GIS数据在线采集简介

    http://blog.csdn.net/gisshixisheng/article/details/44310765 在前一篇博文“Arcgis for js之WKT和geometry转换”中实现了 ...

  4. 微信小程序animation

    wxml <view class="background" animation="{{rotateData}}"> </view>< ...

  5. BZOJ 2850: 巧克力王国 KDtree + 估价函数

    Code: #include<bits/stdc++.h> #define maxn 100000 #define inf 1000000008 #define mid ((l+r)> ...

  6. map集合遍历,放入id

    背景,需要从电脑导入excel表格到网页上然后表格中公司需要对应数据库的id 通过key-value方法来对应id Office office = new Office();office.setG00 ...

  7. vue自定义轻量级form表单校验

    遇到了form表单提交的需求,找了vue的组件觉得不够灵活,有时间自己写了一个. 调用方法 全局引入注册: import va from 'global/js/va' va.install(Vue); ...

  8. 非递归全排列 python实现

    python algorithm 全排列(Permutation) 排列(英语:Permutation)是将相异物件或符号根据确定的顺序重排.每个顺序都称作一个排列.例如,从一到六的数字有720种排列 ...

  9. 第四节:DataFrame属性及方法(下)

  10. WPF Style设置和模板化Template

    WPF样式设置和模板化是一套功能(样式,模板,触发器和演示图版),可以为产品设置统一外观.类似于html的css,可以快速的设置一系列属性值到控件. 案例:ButtonStyle 这里创建了一个目标类 ...