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两节点之间的路径上点权值在[a,b]之间的点权总和
分析:
求出每个询问的LCA,然后离线
按dfs顺序更新树状数组,即某点处树状数组中存的值为其所有祖先节点的值
每个点处对答案的贡献为:
当其为第 i 个 lca 时, ans[i] -= 2 * query(a,b) , 再特判该节点
当其为第 i 个 s,t 时, ans[i] += query(a,b)
*/
#include <bits/stdc++.h>
using namespace std;
#define LL long long
const int N = 1e5+5;
typedef pair<int, int> P;
vector<int> G[N];//存边
vector<P> QQ[N];
int a[N], b[N*4], cnt, n, Q;
struct Query {
int s, t, lca, a, b;
}q[N];
void addedge(int u, int v) {
G[u].push_back(v);
}
namespace LCA {
struct Query {
int v, q;
}; vector <Query> query[N];//存每个点的询问
int ans[N], f[N], vis[N];
int sf(int x) {
return x == f[x] ? x : f[x] = sf(f[x]);
}
void init() {
memset(ans, -1, sizeof(ans));
for (int i = 0; i < N; i++) {
vis[i] = 0; f[i] = i; query[i].clear();
}
}
void adq(int u, int v, int id) {//添加询问
query[u].push_back(Query{v, id});
query[v].push_back(Query{u, id});
}
void LCA(int u) {
f[u] = u, vis[u] = 1;
for (auto& x : query[u]) {
if (vis[x.v] && ans[x.q] == -1)
ans[x.q] = sf(x.v);
}
for (auto& v : G[u]) {
if (vis[v]) continue;
LCA(v);
f[v] = u;
}
}
}
void init2()
{
cnt = 0;
for (int i = 1; i <= n; i++) b[++cnt] = a[i];
for (int i = 1; i <= Q; i++)
{
b[++cnt] = q[i].a;
b[++cnt] = q[i].b;
}
sort(b+1, b+cnt+1);
cnt = unique(b+1, b+cnt+1) - (b+1);
for (int i = 1; i <= n; i++)
a[i] = lower_bound(b+1, b+cnt+1, a[i]) - b;
for (int i = 1; i <= Q; i++)
{
q[i].a = lower_bound(b+1, b+cnt+1, q[i].a) - b;
q[i].b = lower_bound(b+1, b+cnt+1, q[i].b) - b;
}
}
LL ans[N], c[N<<4];
void modify(int x, LL num){
while (x <= cnt) c[x] += num, x += x&-x;
}
LL sum(int x) {
LL s = 0;
while (x) s += c[x], x -= x&-x;
return s;
}
void init()
{
memset(c, 0, sizeof(c));
for (int i = 0; i < N; i++) G[i].clear();
for (int i = 0; i < N; i++) QQ[i].clear();
memset(ans, 0, sizeof(ans));
}
void dfs(int u, int pre)
{
modify(a[u], b[a[u]]);
LL tmp;
for (auto & qq : QQ[u])
{
tmp = sum(q[qq.first].b) - sum(q[qq.first].a-1);
if (qq.second == -1)
{
ans[qq.first] -= 2*tmp;
if (a[u] >= q[qq.first].a && a[u] <= q[qq.first].b)
ans[qq.first] += b[a[u]];
}
else
{
ans[qq.first] += tmp;
}
}
for (auto&v: G[u])
{
if (v == pre) continue;
dfs(v, u);
}
modify(a[u], -b[a[u]]);
}
int main()
{
int u, v;
while (~scanf("%d%d", &n, &Q))
{
init();
for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
for (int i = 1; i < n; i++)
{
scanf("%d%d", &u, &v);
addedge(u, v); addedge(v, u);
}
for (int i = 1; i <= Q; i++)
scanf("%d%d%d%d", &q[i].s, &q[i].t, &q[i].a, &q[i].b);
init2();
LCA::init();
for (int i = 1; i <= Q; i++) LCA::adq(q[i].s, q[i].t, i);
LCA::LCA(1);
for (int i = 1; i <= Q; i++)
{
q[i].lca = LCA::ans[i];
QQ[q[i].lca].push_back(P(i, -1));
QQ[q[i].s].push_back(P(i, 1));
QQ[q[i].t].push_back(P(i, 1));
}
dfs(1, 1);
for (int i = 1; i < Q; i++) printf("%lld ", ans[i]);
printf("%lld\n", ans[Q]);
}
}
HDU 6162 - Ch’s gift | 2017 ZJUT Multi-University Training 9的更多相关文章
- 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 ...
- 2017多校第9场 HDU 6162 Ch’s gift 树剖加主席树
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6162 题意:给出一棵树的链接方法,每个点都有一个数字,询问U->V节点经过所有路径中l < ...
- 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 ...
- HDU 6162 Ch's gift(树链剖分+线段树)
题意: 已知树上的每个节点的值和节点之间的关系建成了一棵树,现在查询节点u到节点v的最短路径上的节点值在l到r之间的节点值的和. 思路: 用树链剖分将树映射到线段树上,线段树上维护3个值,max,mi ...
- HDU 6162 Ch’s gift (线段树+树链剖分)
题意:给定上一棵树,每个树的结点有一个权值,有 m 个询问,每次询问 s, t , a, b,问你从 s 到 t 这条路上,权值在 a 和 b 之间的和.(闭区间). 析:很明显的树链剖分,但是要用 ...
- HDU 6170 - Two strings | 2017 ZJUT Multi-University Training 9
/* HDU 6170 - Two strings [ DP ] | 2017 ZJUT Multi-University Training 9 题意: 定义*可以匹配任意长度,.可以匹配任意字符,问 ...
- L - Ch’s gift HDU - 6162
Ch’s gift Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total S ...
- HDU 6168 - Numbers | 2017 ZJUT Multi-University Training 9
/* HDU 6168 - Numbers [ 思维 ] | 2017 ZJUT Multi-University Training 9 题意: .... 分析: 全放入multiset 从小到大,慢 ...
随机推荐
- [转帖]使用Nginx转发TCP/UDP数据
使用Nginx转发TCP/UDP数据 https://www.cnblogs.com/guigujun/p/8075620.html 编译安装Nginx 从1.9.0开始,nginx就支持对TCP的转 ...
- Python 解LeetCode:394 Decode String
题目描述:按照规定,把字符串解码,具体示例见题目链接 思路:使用两个栈分别存储数字和字母 注意1: 数字是多位的话,要处理后入数字栈 注意2: 出栈时过程中产生的组合后的字符串要继续入字母栈 注意3: ...
- 链表习题(1)-设计一个递归算法,删除不带头结点的单链表L中所有值为x的结点
/*设计一个递归算法,删除不带头结点的单链表L中所有值为x的结点*/ /* 算法思想:设f(L,x)的功能是删除以L为首结点指针的单链表中所有值等于x的结点, 则显然有f(L->next,x)的 ...
- WUSTOJ 1338: The minimum square sum(Java)
题目链接:1338: The minimum square sum Description Given a prime p(p<108), you are to find min{x2+y2}, ...
- Docker 学习笔记(四):问题日志
一.Docker-Compose 容器组开机重启失败 Docker-Compose 的 depends_on 参数在 docker 中没有对应. 重启电脑后,容器的重启过程只由 docker 控制,而 ...
- DEFAULT CURRENT_TIMESTAMP
alter table t_user_channel_info change update_dttm update_dttm timestamp NOT NULL DEFAULT CURRENT_TI ...
- 详解Ubuntu16.04安装Python3.7及其pip3并切换为默认版本(转)
原文:https://www.jb51.net/article/156927.htm
- flume-ng version出现错误Error: Could not find or load main class org.apache.flume.tools.GetJavaPrope的解决办法
错误: 找不到或无法加载主类 org.apache.flume.tools.GetJavaProperty或者Error: Could not find or load main class org. ...
- myisam和innodb的区别,java事务不起作用原因
myisam:只支持表级锁.不支持事务.方便移植.该类型是mysql默认表存储类型 innodb:支持表级锁和行级锁.支持事务. 如果你的事务不起作用,很可能是用了myisam存储引擎,检查数据表引擎 ...
- POJ1222、POJ3279、POJ1753--Flip
POJ1222-EXTENDED LIGHTS OUT POJ3279-Fliptile POJ1753-Flip Game 为什么将着三个题放一起讲呢?因为只要搞明白了其中一点,就可以一次3ac了- ...