HDU 6162 Ch’s gift (线段树+树链剖分)
题意:给定上一棵树,每个树的结点有一个权值,有 m 个询问,每次询问 s, t , a, b,问你从 s 到 t 这条路上,权值在 a 和 b 之间的和。(闭区间)。
析:很明显的树链剖分,但是要用线段树来维护,首先先离线,然后按询问的 a 排序,每次把小于 a 的权值先更新上,然后再查询,这样就是区间求和了,算完小于a的,再算b的,最答案相减就好了。
代码如下:
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <cctype>
#include <cmath>
#include <stack>
#include <sstream>
#include <list>
#include <assert.h>
#include <bitset>
#define debug() puts("++++");
#define gcd(a, b) __gcd(a, b)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define fi first
#define se second
#define pb push_back
#define sqr(x) ((x)*(x))
#define ms(a,b) memset(a, b, sizeof a)
#define sz size()
#define pu push_up
#define pd push_down
#define cl clear()
#define all 1,n,1
#define FOR(x,n) for(int i = (x); i < (n); ++i)
#define freopenr freopen("in.txt", "r", stdin)
#define freopenw freopen("out.txt", "w", stdout)
using namespace std; typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f;
const double inf = 1e20;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int maxn = 1e5 + 10;
const LL mod = 1e9 + 7;
const int dr[] = {-1, 0, 1, 0};
const int dc[] = {0, 1, 0, -1};
const char *de[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
int n, m;
const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
inline bool is_in(int r, int c) {
return r > 0 && r <= n && c > 0 && c <= m;
} struct Val{
int x, id;
};
Val a[maxn]; struct Edge{
int to, next;
};
Edge edge[maxn<<1];
int head[maxn<<1], cnt; void add(int u, int v){
edge[cnt].to = v;
edge[cnt].next = head[u];
head[u] = cnt++;
} struct Query{
int s, t, a, b;
int id;
};
Query q[maxn]; inline bool cmpVal(const Val &lhs, const Val &rhs){
return lhs.x < rhs.x;
} inline bool cmpL(const Query &lhs, const Query &rhs){
return lhs.a < rhs.a;
} inline bool cmpR(const Query &lhs, const Query &rhs){
return lhs.b < rhs.b;
} int fa[maxn], top[maxn], p[maxn];
int pos, son[maxn], num[maxn], dep[maxn]; void init(){
cnt = 0; pos = 0;
ms(head, -1);
ms(son, -1);
} void dfs1(int u, int f, int d){
fa[u] = f; dep[u] = d;
num[u] = 1;
for(int i = head[u]; ~i; i = edge[i].next){
int v = edge[i].to;
if(v == f) continue;
dfs1(v, u, d+1);
num[u] += num[v];
if(son[u] == -1 || num[son[u]] < num[v]) son[u] = v;
}
} void dfs2(int u, int sp){
top[u] = sp;
p[u] = ++pos;
if(son[u] == -1) return ;
dfs2(son[u], sp);
for(int i = head[u]; ~i; i = edge[i].next){
int v = edge[i].to;
if(v == son[u] || v == fa[u]) continue;
dfs2(v, v);
}
} LL sum[maxn<<2]; void push_up(int rt){
sum[rt] = sum[rt<<1] + sum[rt<<1|1];
} void update(int M, int val, int l, int r, int rt){
if(l == r){ sum[rt] = val; return ; }
int m = l + r >> 1;
if(M <= m) update(M, val, lson);
else update(M, val, rson);
pu(rt);
} LL query(int L, int R, int l, int r, int rt){
if(L <= l && r <= R) return sum[rt];
int m = l + r >> 1;
LL ans = 0;
if(L <= m) ans = query(L, R, lson);
if(R > m) ans += query(L, R, rson);
return ans;
} LL solve(int u, int v){
int f1 = top[u], f2 = top[v];
LL ans = 0;
while(f1 != f2){
if(dep[f1] < dep[f2]){
swap(f1, f2);
swap(u, v);
}
ans += query(p[f1], p[u], all);
u = fa[f1];
f1 = top[u];
}
if(dep[u] > dep[v]) swap(u, v);
return ans += query(p[u], p[v], all);
} LL ansL[maxn], ansR[maxn]; int main(){
while(scanf("%d %d", &n, &m) == 2){
init();
for(int i = 1; i <= n; ++i){
scanf("%d", &a[i].x);
a[i].id = i;
}
for(int i = 1; i < n; ++i){
int u, v;
scanf("%d %d", &u, &v);
add(u, v);
add(v, u);
}
dfs1(1, -1, 0);
dfs2(1, 1);
for(int i = 0; i < m; ++i){
scanf("%d %d %d %d", &q[i].s, &q[i].t, &q[i].a, &q[i].b);
--q[i].a;
q[i].id = i;
}
ms(sum, 0);
sort(a + 1, a + n + 1, cmpVal);
sort(q, q + m, cmpL);
int idx = 1;
for(int i = 0; i < m; ++i){
while(idx <= n && a[idx].x <= q[i].a) update(p[a[idx].id], a[idx].x, all), idx++;
ansL[q[i].id] = solve(q[i].s, q[i].t);
}
ms(sum, 0);
sort(q, q + m, cmpR);
idx = 1;
for(int i = 0; i < m; ++i){
while(idx <= n && a[idx].x <= q[i].b) update(p[a[idx].id], a[idx].x, all), idx++;
ansR[q[i].id] = solve(q[i].s, q[i].t);
}
for(int i = 0; i < m; ++i){
if(i) putchar(' ');
printf("%I64d", ansR[i]-ansL[i]);
}
printf("\n");
}
return 0;
}
HDU 6162 Ch’s gift (线段树+树链剖分)的更多相关文章
- HDU 6162 - Ch’s gift | 2017 ZJUT Multi-University Training 9
/* HDU 6162 - Ch’s gift [ LCA,线段树 ] | 2017 ZJUT Multi-University Training 9 题意: N节点的树,Q组询问 每次询问s,t两节 ...
- 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 ...
- HDU 6162 Ch’s gift (树剖 + 离线线段树)
Ch’s gift Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total S ...
- HDU 6162 Ch's gift(树链剖分+线段树)
题意: 已知树上的每个节点的值和节点之间的关系建成了一棵树,现在查询节点u到节点v的最短路径上的节点值在l到r之间的节点值的和. 思路: 用树链剖分将树映射到线段树上,线段树上维护3个值,max,mi ...
- 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 ...
- 2017多校第9场 HDU 6162 Ch’s gift 树剖加主席树
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6162 题意:给出一棵树的链接方法,每个点都有一个数字,询问U->V节点经过所有路径中l < ...
- 线段树&数链剖分
傻逼线段树,傻逼数剖 线段树 定义: 线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点. 使用线段树可以快速的查找某一个节点在若干条线段中出现 ...
- UOJ#30/Codeforces 487E Tourists 点双连通分量,Tarjan,圆方树,树链剖分,线段树
原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ30.html 题目传送门 - UOJ#30 题意 uoj写的很简洁.清晰,这里就不抄一遍了. 题解 首先建 ...
- BZOJ1758[Wc2010]重建计划——分数规划+长链剖分+线段树+二分答案+树形DP
题目描述 输入 第一行包含一个正整数N,表示X国的城市个数. 第二行包含两个正整数L和U,表示政策要求的第一期重建方案中修建道路数的上下限 接下来的N-1行描述重建小组的原有方案,每行三个正整数Ai, ...
随机推荐
- hdu1010 Tempter of the Bone(深搜+剪枝问题)
Tempter of the Bone Time Limit: / MS (Java/Others) Memory Limit: / K (Java/Others) Total Submission( ...
- PolyBase 指南
PolyBase 是一种可通过 t-sql 语言访问数据库外部数据的技术.PolyBase is a technology that accesses data outside of the data ...
- 关于SQLSERVER的全文目录跟全文索引的区别
很久没有写随笔了,本来之前想写一篇关于SQLSERVER全文索引的随笔,可惜没有时间,一直拖到现在才有时间写,不好意思让各位久等了~ 先介绍一下SQLSERVER中的存储类对象,哈哈,先介绍一下概念嘛 ...
- 灾难恢复:RPO与RTO
许多企事业单位虽然已经认识到信息安全的重要性,却迟迟没有行动.其中的原因是多方面的,最主要的一个原因就是在如何建立容灾系统的问题上存在种种疑惑.容灾设计指标主要与容灾系统的数据恢复能力有关,最常见的设 ...
- centos 6.3 kickstart 装机卡在 unsupported hardware detected 页面
起因 最近厂里一批 dell 新机器 centos 6.3 装机卡在 Unsupported Hardware Detected 页面,要人肉点击 OK 才能继续装机: Unsupported Har ...
- Flask之模板之宏、继承、包含
3.5 宏.继承.包含 类似于python中的函数,宏的作用就是在模板中重复利用代码,避免代码冗余. Jinja2支持宏,还可以导入宏,需要在多处重复使用的模板代码片段可以写入单独的文件,再包含在所有 ...
- Service和Thread的关系
Service确实是运行在主线程里的,也就是说如果你在Service里编写了非常耗时的代码,程序必定有问题. Android的后台就是指,它的运行是完全不依赖UI的.即使Activity被销毁,或者程 ...
- C# WinForm启动时的事件加载次序
- java byte to hex
String str; byte[] bs = null; bs =str.getBytes(); bs =str.getBytes("utf-8") java byte to ...
- Sass 入门 (一) 安装Sass
Sass安装 ruby安装 因为sass依赖于ruby环境,所以装sass之前先确认装了ruby.先导官网下载个ruby 在安装的时候,请勾选Add Ruby executables to your ...