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. hdu 3033 I love sneakers!(分组背包+每组至少选一个)

    I love sneakers! Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  2. 【算法】分块——教主的魔法&不勤劳的图书管理员

    由不勤劳的图书管理员带入了分块的坑,深深地被其暴力与优雅所征服.分块的实质就是将暴力块状封装起来,一整块的部分就一整块处理,零碎的部分就怎么暴力怎么来.因为分块大小的原因,限制了零碎部分数据的数量级, ...

  3. [国家集训队]Crash的数字表格 / JZPTAB 莫比乌斯反演

    ---题面--- 题解: $$ans = \sum_{i = 1}^{n}\sum_{j = 1}^{m}{\frac{ij}{gcd(i, j)}}$$ 改成枚举d(设n < m) $$ans ...

  4. Android逆向之旅---静态方式分析破解视频编辑应用「Vue」水印问题

    一.故事背景 现在很多人都喜欢玩文艺,特别是我身边的UI们,拍照一分钟修图半小时.就是为了能够在朋友圈显得逼格高,不过的确是挺好看的,修图的软件太多了就不多说了,而且一般都没有水印啥的.相比较短视频有 ...

  5. uva10884 Persephone

    题目戳这里. 找规律. 每一列占据的格子一定是一段区间: 相邻列之间的区间有交. 上界先增后减,下界先减后增. \(f_{i,j,k,0/1,0/1}\)表示考虑前\(i\)列,第\(i\)列,上界为 ...

  6. Palindrome [Manecher]

    Palindrome Time Limit: 15000MS Memory Limit: 65536K Total Submissions: 12214 Accepted: 4583 Descript ...

  7. handler更新ui线程的基本用法

    1.因为费时操作要放子线程,更新UI要放UI线程(主线程),所以子线程和主线程通信,通信的话要用到handler这个东西. 这里讲的比较简单,举2个例子说明 2.使用post的是handler ,使用 ...

  8. NYOJ 20 吝啬的国度 (深搜)

    题目链接 描述 在一个吝啬的国度里有N个城市,这N个城市间只有N-1条路把这个N个城市连接起来.现在,Tom在第S号城市,他有张该国地图,他想知道如果自己要去参观第T号城市,必须经过的前一个城市是几号 ...

  9. [bzoj3226][Sdoi2008]校门外的区间——线段树

    题目 略 题解 直接套黄学长模板. Orz 代码 #include <bits/stdc++.h> using namespace std; #define ll long long #d ...

  10. HoneyPy 模拟Nginx服务器脚本

    HoneyPy是一个Python写的低交互式蜜罐,可以通过自定义Plugins的方式来配置不同的场景.这里是一个模拟Nginx空白页面的代码: # Auth xiaoxiaoleo # http:// ...