hdu6162

题意

给出一颗带点权的树,每次询问一对节点 \((u, v)\),问 \(u\) 到 \(v\) 的最短路径上所有节点权值在 \([c1, c2]\) 区间内的和。

分析

树链剖分,那么我们只需要处理一个区间内节点权值在 \([c1, c2]\) 之间的和。建一颗线段树,每个节点维护当前区间内所有的点已经排序后的权值,以及前缀和。那么两次二分,前缀和相减就可以快速得到区间内权值在 \([c1, c2]\) 的所有节点的和。

code

#include<bits/stdc++.h>
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
using namespace std;
typedef long long ll;
const int MAXN = 1e5 + 10;
int n, m;
int fa[MAXN]; // fa[v]: v 的父亲
int dep[MAXN]; // dep[v]: v 的深度(根深度为1)
int siz[MAXN]; // : 以 v 为根的子树的节点数
int son[MAXN]; // : 重儿子,siz[u] 为 v 的子节点中 siz 值最大的,那么 u 就是 v 的重儿子
int top[MAXN]; // : 表示 v 所在的重链的顶端节点
int w[MAXN]; // : 表示 v 在线段树中的位置
int num; // 将树映射到线段树上的标号
int cnt, head[MAXN << 1];
struct Edge {
int to, next;
}edge[MAXN << 1];
void addedge(int u, int v) {
edge[cnt].to = v;
edge[cnt].next = head[u];
head[u] = cnt++;
}
int tre[MAXN]; // 线段树上的点在树上的节点编号
int cost[MAXN];
void dfs(int u) {
siz[u] = 1; son[u] = 0;
for(int i = head[u]; ~i; i = edge[i].next) {
if(edge[i].to != fa[u]) {
fa[edge[i].to] = u;
dep[edge[i].to] = dep[u] + 1;
dfs(edge[i].to);
if(siz[edge[i].to] > siz[son[u]]) son[u] = edge[i].to;
siz[u] += siz[edge[i].to];
}
}
}
void build_tree(int u, int tp) {
w[u] = ++num; top[u] = tp;
if(son[u]) build_tree(son[u], top[u]); // 使重链各边在线段树中呈连续分布
for(int i = head[u]; ~i; i = edge[i].next) {
int v = edge[i].to;
if(v != son[u] && v != fa[u])
build_tree(v, v);
}
}
vector<int> v[MAXN << 2];
vector<ll> sum[MAXN << 2];
void pushUp(int rt) {
v[rt].resize(v[rt << 1].size() + v[rt << 1 | 1].size());
merge(v[rt << 1].begin(), v[rt << 1].end(), v[rt << 1 | 1].begin(), v[rt << 1 | 1].end(), v[rt].begin());
sort(v[rt].begin(), v[rt].end());
ll s = 0;
for(int i = 0; i < v[rt].size(); i++) {
s += v[rt][i];
sum[rt].push_back(s);
}
}
void build(int l, int r, int rt) {
v[rt].clear();
sum[rt].clear();
if(l == r) {
v[rt].push_back(cost[tre[l]]);
sum[rt].push_back(cost[tre[l]]);
return;
}
int m = (l + r) / 2;
build(lson);
build(rson);
pushUp(rt);
}
ll query(int L, int R, int c1, int c2, int l, int r, int rt) {
if(L <= l && R >= r) {
int posr = upper_bound(v[rt].begin(), v[rt].end(), c2) - v[rt].begin(); posr--;
int posl = lower_bound(v[rt].begin(), v[rt].end(), c1) - v[rt].begin(); posl--;
ll x = posr < 0 ? 0 : sum[rt][posr];
ll y = posl < 0 ? 0 : sum[rt][posl];
return x - y;
}
int m = (l + r) / 2;
ll res = 0;
if(m >= L) res += query(L, R, c1, c2, lson);
if(m < R) res += query(L, R, c1, c2, rson);
return res;
}
ll seek(int v, int u, int c1, int c2) {
int t1 = top[v], t2 = top[u];
ll res = 0;
while(t1 != t2) {
if(dep[t1] < dep[t2]) {
swap(t1, t2); swap(v, u);
}
res += query(w[t1], w[v], c1, c2, 1, n, 1);
v = fa[t1]; t1 = top[v];
}
if(dep[v] > dep[u]) swap(v, u);
return res + query(w[v], w[u], c1, c2, 1, n, 1);
}
//适用于正整数
template <class T>
inline void scan_d(T &ret) {
char c; ret=0;
while((c=getchar())<'0'||c>'9');
while(c>='0'&&c<='9') ret=ret*10+(c-'0'),c=getchar();
}
int main() {
while(~scanf("%d%d", &n, &m)) {
memset(head, -1, sizeof head);
cnt = num = 0;
for(int i = 1; i <= n; i++) {
scanf("%d", &cost[i]);
}
for(int i = 0; i < n - 1; i++) {
int u, v;
scanf("%d%d", &u, &v);
addedge(u, v);
addedge(v, u);
}
dfs(1);
build_tree(1, 1);
for(int i = 1; i <= n; i++) {
tre[w[i]] = i;
}
build(1, n, 1);
for(int i = 0; i < m; i++) {
int l, r, c1, c2;
scan_d(l); scan_d(r); scan_d(c1); scan_d(c2);
printf("%lld%c", seek(l, r, c1, c2), " \n"[i == m - 1]);
}
}
return 0;
}

hdu6162(树链剖分)的更多相关文章

  1. BZOJ 3626: [LNOI2014]LCA [树链剖分 离线|主席树]

    3626: [LNOI2014]LCA Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2050  Solved: 817[Submit][Status ...

  2. BZOJ 1984: 月下“毛景树” [树链剖分 边权]

    1984: 月下“毛景树” Time Limit: 20 Sec  Memory Limit: 64 MBSubmit: 1728  Solved: 531[Submit][Status][Discu ...

  3. codevs 1228 苹果树 树链剖分讲解

    题目:codevs 1228 苹果树 链接:http://codevs.cn/problem/1228/ 看了这么多树链剖分的解释,几个小时后总算把树链剖分弄懂了. 树链剖分的功能:快速修改,查询树上 ...

  4. 并查集+树链剖分+线段树 HDOJ 5458 Stability(稳定性)

    题目链接 题意: 有n个点m条边的无向图,有环还有重边,a到b的稳定性的定义是有多少条边,单独删去会使a和b不连通.有两种操作: 1. 删去a到b的一条边 2. 询问a到b的稳定性 思路: 首先删边考 ...

  5. 树链剖分+线段树 CF 593D Happy Tree Party(快乐树聚会)

    题目链接 题意: 有n个点的一棵树,两种操作: 1. a到b的路径上,给一个y,对于路径上每一条边,进行操作,问最后的y: 2. 修改某个条边p的值为c 思路: 链上操作的问题,想树链剖分和LCT,对 ...

  6. 树链剖分+线段树 HDOJ 4897 Little Devil I(小恶魔)

    题目链接 题意: 给定一棵树,每条边有黑白两种颜色,初始都是白色,现在有三种操作: 1 u v:u到v路径(最短)上的边都取成相反的颜色 2 u v:u到v路径上相邻的边都取成相反的颜色(相邻即仅有一 ...

  7. bzoj2243树链剖分+染色段数

    终于做了一道不是一眼出思路的代码题(⊙o⊙) 之前没有接触过这种关于染色段数的题目(其实上课好像讲过),于是百度了一下(现在思维能力好弱) 实际上每一段有用的信息就是总共有几段和两段各是什么颜色,在开 ...

  8. bzoj3631树链剖分

    虽然是水题1A的感觉太爽了O(∩_∩)O~ 题意相当于n-1次树上路径上每个点权值+1,最后问每个点的权值 本来想写线段树,写好了change打算框架打完了再来补,结果打完发现只是区间加和单点查 前缀 ...

  9. BZOJ 3531: [Sdoi2014]旅行 [树链剖分]

    3531: [Sdoi2014]旅行 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1685  Solved: 751[Submit][Status] ...

随机推荐

  1. 【题解】SCOI2010幸运数字

    最近在学习容斥相关,于是就看到了这个题.一开始以为是补集转化,但是观察一下马上发现不可行,好像直接做会比较容易一些.一个数满足要求的充要条件即为是一个幸运数字的倍数,那么容斥可以轻松搞定,只要枚举是一 ...

  2. BZOJ3132 上帝造题的七分钟 【二维树状数组】

    题目 "第一分钟,X说,要有矩阵,于是便有了一个里面写满了0的n×m矩阵. 第二分钟,L说,要能修改,于是便有了将左上角为(a,b),右下角为(c,d)的一个矩形区域内的全部数字加上一个值的 ...

  3. bzoj 1977 洛谷P4180 严格次小生成树

    Description: 给定一张N个节点M条边的无向图,求该图的严格次小生成树.设最小生成树边权之和为sum,那么严格次小生成树就是边权之和大于sum的最小的一个 Input: 第一行包含两个整数N ...

  4. 【bzoj3224】Tyvj 1728 普通平衡树 01Trie姿势+平衡树的四种姿势 :splay,旋转Treap,非旋转Treap,替罪羊树

    直接上代码 正所谓 人傻自带大常数 平衡树的几种姿势:  AVL Red&Black_Tree 码量爆炸,不常用:SBT 出于各种原因,不常用. 常用: Treap 旋转 基于旋转操作和随机数 ...

  5. chrome 不支持12px以下字体为题的解决

    现英文9px 设置 在chrome 下无效,可以通过 -webkit-transform: scale(0.75); 12*0.75 =9  得到小字体(在chrome浏览器下 大小缩放到0.75倍) ...

  6. 文件格式转换神器-pandoc

    By francis_hao    Mar 11,2017 介绍 如果你需要在各种类型的文件中穿梭,那么你需要这把瑞士军刀-pandoc 它可以将各种常见的不常见的文件类型转换成另一种,我感兴趣的是在 ...

  7. [bzoj 1143]最长反链二分图最大匹配

    Dilworth定理:偏序集能划分成的最少的全序集的个数与最大反链的元素个数相等. 证明:http://www.cnblogs.com/itlqs/p/6636222.html 题目让求的是最大反链的 ...

  8. POJ - 1017 贪心训练

    Packets Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 59725   Accepted: 20273 Descrip ...

  9. IDEA 使用maven创建web项目,打包war时不会创建class文件

    使用maven创建项目后我有创建了个src的目录,导致maven编译不能识别我创建的src文件下的Java文件 修改这样后就可以识别编译Java文件 今天又给自己挖了个坑.......

  10. [洛谷P1528] 切蛋糕

    洛谷题目链接:切蛋糕 题目描述 Facer今天买了n块蛋糕,不料被信息组中球球等好吃懒做的家伙发现了,没办法,只好浪费一点来填他们的嘴巴.他答应给每个人留一口,然后量了量每个人口的大小.Facer有把 ...