You are given a tree with N nodes. The tree nodes are numbered from 1 to N. Each node has an integer weight.

We will ask you to perform the following operation:

  • u v k : ask for the kth minimum weight on the path from node u to node v

Input

In the first line there are two integers N and M. (N, M <= 100000)

In the second line there are N integers. The ith integer denotes the weight of the ith node.

In the next N-1 lines, each line contains two integers u v, which describes an edge (uv).

In the next M lines, each line contains three integers u v k, which means an operation asking for the kth minimum weight on the path from node u to node v.

Output

For each operation, print its result.

Example

Input:
8 5
105 2 9 3 8 5 7 7
1 2
1 3
1 4
3 5
3 6
3 7
4 8
2 5 1
2 5 2
2 5 3
2 5 4
7 8 2 
Output:
2
8
9
105

给出一棵树,每个点都自己的权重,然后给出树上的边,要求从节点 u 到节点 v 路径上的第 k 小的权重的大小。
因为权重可能很大,所以需要离散化。
主席树求区间第 k 小维护的是权值线段树的前缀和,然后通过区间相减得到查询区间的权值线段树
所以树形结构的第 k 小维护的也是权值线段树的前缀和,这里的前缀和表示从第 i 个结点到根的前缀和,比如样例的树是

那么我们用主席树把这八个结点维护成这个样子

那么要得到其中两个点(u,v)之间的树形结构,就可以看成 TREE(u) + TREE(v) - TREE(lca(u,v))- TREE(fa(lca(u,v))),把查询看成四棵树之间的相加相减,然后在求一下lca(u,v)就可以了,这里我比较懒直接用在线的写了

 /*
.
';;;;;.
'!;;;;;;!;`
'!;|&#@|;;;;!:
`;;!&####@|;;;;!:
.;;;!&@$$%|!;;;;;;!'.`:::::'.
'!;;;;;;;;!$@###&|;;|%!;!$|;;;;|&&;.
:!;;;;!$@&%|;;;;;;;;;|!::!!:::;!$%;!$%` '!%&#########@$!:.
;!;;!!;;;;;|$$&@##$;;;::'''''::;;;;|&|%@$|;;;;;;;;;;;;;;;;!$;
;|;;;;;;;;;;;;;;;;;;!%@#####&!:::;!;;;;;;;;;;!&####@%!;;;;$%`
`!!;;;;;;;;;;!|%%|!!;::;;|@##%|$|;;;;;;;;;;;;!|%$#####%;;;%&;
:@###&!:;;!!||%%%%%|!;;;;;||;;;;||!$&&@@%;;;;;;;|$$##$;;;%@|
;|::;;;;;;;;;;;;|&&$|;;!$@&$!;;;;!;;;;;;;;;;;;;;;;!%|;;;%@%.
`!!;;;;;;;!!!!;;;;;$@@@&&&&&@$!;!%|;;;;!||!;;;;;!|%%%!;;%@|.
%&&$!;;;;;!;;;;;;;;;;;|$&&&&&&&&&@@%!%%;!||!;;;;;;;;;;;;;$##!
!%;;;;;;!%!:;;;;;;;;;;!$&&&&&&&&&&@##&%|||;;;!!||!;;;;;;;$&:
':|@###%;:;;;;;;;;;;;;!%$&&&&&&@@$!;;;;;;;!!!;;;;;%&!;;|&%.
!@|;;;;;;;;;;;;;;;;;;|%|$&&$%&&|;;;;;;;;;;;;!;;;;;!&@@&'
.:%#&!;;;;;;;;;;;;;;!%|$$%%&@%;;;;;;;;;;;;;;;;;;;!&@:
.%$;;;;;;;;;;;;;;;;;;|$$$$@&|;;;;;;;;;;;;;;;;;;;;%@%.
!&!;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;|@#;
`%$!;;;;;;;;;;;$@|;;;;;;;;;;;;;;;;;;;;;;;;!%$@#@|.
.|@%!;;;;;;;;;!$&%||;;;;;;;;;;;;;;;;;!%$$$$$@#|.
;&$!;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;%#####|.
|##$|!;;;;;;::'':;;;;;;;;;;;;;!%$$$@#@;
;@&|;;;;;;;::'''''':;;;;;;;|$&@###@|`
.%##@|;;;;:::''''''''''::;!%&##$'
`$##@$$@@&|!!;;;:'''''::::;;;;;|&#%.
;&@##&$%!;;;;;;::''''''''::;!|%$@#@&@@:
.%@&$$|;;;;;;;;;;:'''':''''::;;;%@#@@#%.
:@##@###@$$$$$|;;:'''':;;!!;;;;;;!$#@@#$;`
`%@$$|;;;;;;;;:'''''''::;;;;|%$$|!!&###&'
|##&%!;;;;;::''''''''''''::;;;;;;;!$@&:`!'
:;!@$|;;;;;;;::''''''''''':;;;;;;;;!%&@$: !@#$'
|##@@&%;;;;;::''''''''':;;;;;;;!%&@#@$%: '%%!%&;
|&%!;;;;;;;%$!:''''''':|%!;;;;;;;;|&@%||` '%$|!%&;
|@%!;;!!;;;||;:'''''':;%$!;;;;!%%%&#&%$&: .|%;:!&%`
!@&%;;;;;;;||;;;:''::;;%$!;;;;;;;|&@%;!$; `%&%!!$&:
'$$|;!!!!;;||;;;;;;;;;;%%;;;;;;;|@@|!$##; !$!;:!$&:
|#&|;;;;;;!||;;;;;;;;!%|;;;;!$##$;;;;|%' `%$|%%;|&$'
|&%!;;;;;;|%;;;;;;;;$$;;;;;;|&&|!|%&&; .:%&$!;;;:!$@!
`%#&%!!;;;;||;;;;;!$&|;;;!%%%@&!;;;!!;;;|%!;;%@$!%@!
!&!;;;;;;;;;||;;%&!;;;;;;;;;%@&!;;!&$;;;|&%;;;%@%`
'%|;;;;;;;;!!|$|%&%;;;;;;;;;;|&#&|!!||!!|%$@@|'
.!%%&%'`|$; :|$#%|@#&;%#%.
*/
#include <map>
#include <set>
#include <list>
#include <ctime>
#include <cmath>
#include <stack>
#include <queue>
#include <string>
#include <vector>
#include <cstdio>
#include <bitset>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define lowbit(x) x & (-x)
#define mes(a, b) memset(a, b, sizeof a)
#define fi first
#define se second
#define pii pair<int, int>
#define INOPEN freopen("in.txt", "r", stdin)
#define OUTOPEN freopen("out.txt", "w", stdout) typedef unsigned long long int ull;
typedef long long int ll;
const int maxn = 1e5 + ;
const int maxm = 1e5 + ;
const int mod = 1e9 + ;
const ll INF = 1e18 + ;
const int inf = 0x3f3f3f3f;
const double pi = acos(-1.0);
const double eps = 1e-;
using namespace std; int n, m;
int cas, tol, T; struct Node {
int l, r;
int sum;
} node[maxn * ];
int a[maxn];
int rt[maxn];
bool vis[maxn];
int deep[maxn];
int fa[maxn][];
vector<int> vec[maxn];
vector<int> vv; void init() {
tol = ;
mes(a, );
mes(rt, );
mes(fa, );
mes(vis, );
mes(node, );
mes(deep, );
vv.clear();
for(int i=; i<=n; i++)
vec[i].clear();
} int getid(int x) {
return lower_bound(vv.begin(), vv.end(), x) - vv.begin() + ;
} void lca_dfs(int u, int f, int d) {
deep[u] = d;
int len = vec[u].size();
for(int i=; i<len; i++) {
int v = vec[u][i];
if(v == f) continue;
if(fa[v][])continue;
fa[v][] = u;
lca_dfs(v, u, d+);
}
} void lca_update() {
for(int j=; (<<j)<=n; j++) {
for(int i=; i<=n; i++) {
fa[i][j] = fa[fa[i][j-]][j-];
}
}
} int lca_query(int u, int v) {
if(deep[u] < deep[v]) swap(u, v);
int f = deep[u] - deep[v];
for(int i=; (<<i)<=f; i++) {
if(f & (<<i)) {
u = fa[u][i];
}
}
if(u != v) {
for(int i=(int)log2(n); i>=; i--) {
if(fa[u][i] != fa[v][i]) {
u = fa[u][i];
v = fa[v][i];
}
}
u = fa[u][];
}
return u;
} void hjt_update(int l, int r, int &x, int y, int pos) {
tol++;
node[tol] = node[y];
node[tol].sum++;
x = tol;
if(l == r) return ;
int mid = (l + r) >> ;
if(pos <= mid)
hjt_update(l, mid, node[x].l, node[y].l, pos);
else
hjt_update(mid+, r, node[x].r, node[y].r, pos);
} void hjt_build(int u, int f) {
// printf("%d %d\n", u, f);
hjt_update(, n, rt[u], rt[f], getid(a[u]));
vis[u] = true;
int len = vec[u].size();
for(int i=; i<len; i++) {
int v = vec[u][i];
if(vis[v]) continue;
if(v == f) continue;
hjt_build(v, u);
}
} int hjt_query(int l, int r, int x, int y, int lca, int flca, int k) {
if(l == r)
return l;
int mid = (l + r) >> ;
int sum = node[node[x].l].sum + node[node[y].l].sum - node[node[lca].l].sum - node[node[flca].l].sum;
if(k <= sum)
return hjt_query(l, mid, node[x].l, node[y].l, node[lca].l, node[flca].l, k);
else
return hjt_query(mid+, r, node[x].r, node[y].r, node[lca].r, node[flca].r, k-sum);
} int main() {
scanf("%d%d", &n, &m);
init();
for(int i=; i<=n; i++) {
scanf("%d", &a[i]);
vv.push_back(a[i]);
}
sort(vv.begin(), vv.end());
vv.erase(unique(vv.begin(), vv.end()), vv.end());
for(int i=; i<n; i++) {
int u, v;
scanf("%d%d", &u, &v);
vec[u].push_back(v);
vec[v].push_back(u);
}
fa[][] = ;
lca_dfs(, , );
lca_update();
hjt_build(, );
while(m--) {
int u, v, k;
scanf("%d%d%d", &u, &v, &k);
int ans = hjt_query(, n, rt[u], rt[v], rt[lca_query(u, v)], rt[fa[lca_query(u, v)][]], k);
printf("%d\n", vv[ans-]);
}
return ;
}

Count on a tree SPOJ - COT (主席树,LCA)的更多相关文章

  1. Count on a tree SPOJ 10628 主席树+LCA(树链剖分实现)(两种存图方式)

    Count on a tree SPOJ 10628 主席树+LCA(树链剖分实现)(两种存图方式) 题外话,这是我第40篇随笔,纪念一下.<( ̄︶ ̄)↗[GO!] 题意 是说有棵树,每个节点上 ...

  2. SPOJ COT Count on a tree(树上主席树 + LCA 求点第k小)题解

    题意:n个点的树,每个点有权值,问你u~v路径第k小的点的权值是? 思路: 树上主席树就是每个点建一棵权值线段树,具体看JQ博客,LCA用倍增logn求出,具体原理看这里 树上主席树我每个点的存的是点 ...

  3. 【BZOJ2588】Count on a tree 题解(主席树+LCA)

    前言:其实就是主席树板子啦……只不过变成了树上的查询 -------------------------- 题目链接 题目大意:求树上$u$到$v$路径第$k$大数. 查询静态区间第$k$大肯定是用主 ...

  4. ☆ [洛谷P2633] Count on a tree 「树上主席树」

    题目类型:主席树+\(LCA\) 传送门:>Here< 题意:给出一棵树.每个节点有点权.问某一条路径上排名第\(K\)小的点权是多少 解题思路 类似区间第\(K\)小,但放在了树上. 考 ...

  5. BZOJ 2588: Spoj 10628. Count on a tree 树上跑主席树

    2588: Spoj 10628. Count on a tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/J ...

  6. BZOJ2588 Count on a tree 【树上主席树】

    2588: Spoj 10628. Count on a tree Time Limit: 12 Sec  Memory Limit: 128 MB Submit: 7577  Solved: 185 ...

  7. 【洛谷2633】Count on a tree(树上主席树)

    点此看题面 大致题意: 给你一棵树,每次问你两点之间第\(k\)小的点权,强制在线. 主席树 这种题目强制在线一般就是数据结构了. 而看到区间第\(k\)小,很容易就能想到主席树. 至少不会有人想到树 ...

  8. 🔺Count on a tree SPOJ - COT (无能为力。。。)

    https://cn.vjudge.net/problem/SPOJ-COT 插上 大佬的代码 和 我的...以后再看吧... Count on a tree 大佬:http://www.cnblog ...

  9. BZOJ - 2588 Spoj 10628. Count on a tree (可持久化线段树+LCA/树链剖分)

    题目链接 第一种方法,dfs序上建可持久化线段树,然后询问的时候把两点之间的所有树链扒出来做差. #include<bits/stdc++.h> using namespace std; ...

随机推荐

  1. Vue组件的is具体用法

    1.为什么要使用is 在vue的官网组件部分中,有明确的描述:当使用 DOM 作为模板时 (例如,使用 el 选项来把 Vue 实例挂载到一个已有内容的元素上),你会受到 HTML 本身的一些限制,因 ...

  2. 虹软2.0 离线人脸识别 Android 开发 Demo

    环境要求1.运行环境 armeabi-v7a2.系统要求 Android 5.0 (API Level 21)及以上3.开发环境 Android Studio 下载地址:https://github. ...

  3. CSS3(animation, trasfrom)总结

    CSS3(animation, trasfrom)总结 1. Animation 样式写法: 格式: @-浏览器内核-keyframes 样式名 {} 标准写法(chrome safari不支持 @k ...

  4. ubuntu中使用机密数据Secrets

    目录 AptNetCore使用Secrets管理私密数据 前言 使用 设置UserSecretsId 设置机密 代码中访问机密 脚注 AptNetCore使用Secrets管理私密数据 前言 在项目中 ...

  5. MongoDB MapReduce用法简介

    Map-Reduce部分:Map-Reduce相当于关系型数据库中的group by,主要用于统计数据之用.MongoDB提供的Map-Reduce非常灵活,对于大规模数据分析也相当实用. 语法 db ...

  6. 在coding或者github建立个人站点域名绑定

    coding:静态的在域名服务器与是填写pages.coding.me,不是填写{你的名字}.coding.me A型的ip是ping 该域名ip github:上传大项目可能报错(报错名字忘记了), ...

  7. Python运算符之翩若惊鸿,婉若游龙

    python中的运算符算术运算符:主要用于两个对象算数计算(加减乘除等运算)比较运算符:用于两个对象比较(判断是否相等.大于等运算)赋值运算符:用于对象的赋值,将运算符右边的值(或计算结果)赋给运算符 ...

  8. Win32 API翻译

    这是从MSDN里面的Win32 SDK API函数.结构.通知.消息等等超过3000个.其中一半是整理自别人翻译. http://files.cnblogs.com/files/sishenzaixi ...

  9. 我的ElasticSearch之ElasticSearch安装配置环境

    最近一段时间比较忙,都很少来园子逛了,刚好,用到了ElasticSearch,感觉还不错,所以就给大家推荐一下,自己也顺便学习:虽然公司选择用ElasticSearch,但是以前都没有用过这个,而且公 ...

  10. 英语口语练习系列-C22-吃东西

    基础词汇 1. bill [bɪl] n. 账单:钞票:法案:鸟嘴 Bill (人名)比尔 pay the bill 付账单 telephone bill 话费单 electricity bill 电 ...