COT - Count on a tree

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 (u,v).

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
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

【分析】在树上建立主席树,然后LCA。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <time.h>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#define met(a,b) memset(a,b,sizeof a)
#define pb push_back
#define lson(x) ((x<<1))
#define rson(x) ((x<<1)+1)
using namespace std;
typedef long long ll;
const int N=1e5+;
const int M=N*N+;
struct seg {
int lson,rson;
int cnt;
};
struct man{
int to,next;
}edg[*N];
seg T[N*];
int root[N],tot,cnt,n,m;
vector<int>pos;
int arr[N];
int fa[*N][],head[N*],dis[N*],dep[N*];
void init() {
pos.clear();
met(root,);met(head,-);
tot=cnt=;
T[].cnt=T[].lson=T[].rson=;
}
void add(int u,int v){
edg[cnt].to=v;edg[cnt].next=head[u];head[u]=cnt++;
}
void update(int &cur,int ori,int l,int r,int pos,int flag) {
cur=++tot;
T[cur]=T[ori];
T[cur].cnt+=flag;
if(l==r)
return ;
int mid=(l+r)/;
if(pos<=mid)
update(T[cur].lson,T[ori].lson,l,mid,pos,flag);
else
update(T[cur].rson,T[ori].rson,mid+,r,pos,flag);
}
int query(int ru,int rv,int lca,int rlca,int l,int r,int k) {
if(l==r)return l;
int mid=(l+r)/;
int sum=T[T[ru].lson].cnt+T[T[rv].lson].cnt-T[T[lca].lson].cnt-T[T[rlca].lson].cnt;
if(sum>=k)return query(T[ru].lson,T[rv].lson,T[lca].lson,T[rlca].lson,l,mid,k);
else query(T[ru].rson,T[rv].rson,T[lca].rson,T[rlca].rson,mid+,r,k-sum);
}
void dfs(int u,int f){
fa[u][]=f;
for(int i=;i<;i++){
fa[u][i]=fa[fa[u][i-]][i-];
}
update(root[u],root[f],,n,arr[u],);
for(int i=head[u];i!=-;i=edg[i].next){
int v=edg[i].to;
if(v!=f){
dep[v]=dep[u]+;
dfs(v,u);
}
}
}
int LCA(int u,int v){
int U=u,V=v;
if(dep[u]<dep[v])swap(u,v);
for(int i=;i>=;i--){
if(dep[fa[u][i]]>=dep[v]){
u=fa[u][i];
}
}
if(u==v)return (u);
for(int i=;i>=;i--){
if(fa[u][i]!=fa[v][i]){
u=fa[u][i];v=fa[v][i];
}
}
return (fa[u][]);
}
int main(void) {
int i,l,r,k,u,v;
scanf("%d%d",&n,&m);
init();
for (i=; i<=n; ++i) {
scanf("%d",&arr[i]);
pos.push_back(arr[i]);
}
sort(pos.begin(),pos.end());
pos.erase(unique(pos.begin(),pos.end()),pos.end());
int temp_rt=;
for (i=; i<=n; ++i) {
arr[i]=lower_bound(pos.begin(),pos.end(),arr[i])-pos.begin()+;
}
for(int i=;i<n;i++){
scanf("%d%d",&u,&v);
add(u,v);add(v,u);
}
dep[]=;
dfs(,);
for (i=; i<m; ++i) {
scanf("%d%d%d",&u,&v,&k);
int lca=LCA(u,v);
int f=fa[lca][];
printf("%d\n",pos[query(root[u],root[v],root[lca],root[f],,n,k)-]);
}
return ;
}

SPOJ 10628 COT - Count on a tree(在树上建立主席树)(LCA)的更多相关文章

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

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

  2. SPOJ 10628. Count on a tree (树上第k大,LCA+主席树)

    10628. Count on a tree Problem code: COT You are given a tree with N nodes.The tree nodes are number ...

  3. 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 ...

  4. SPOJ - COT Count on a tree

    地址:http://www.spoj.com/problems/COT/en/ 题目: COT - Count on a tree #tree You are given a tree with N  ...

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

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

  6. SPOJ Count on a tree(主席树+LCA)

    一.题目 COT - Count on a tree You are given a tree with N nodes. The tree nodes are numbered from 1 to  ...

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

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

  8. 洛谷P4180 [Beijing2010组队]次小生成树Tree(最小生成树,LCT,主席树,倍增LCA,倍增,树链剖分)

    洛谷题目传送门 %%%TPLY巨佬和ysner巨佬%%% 他们的题解 思路分析 具体思路都在各位巨佬的题解中.这题做法挺多的,我就不对每个都详细讲了,泛泛而谈吧. 大多数算法都要用kruskal把最小 ...

  9. SPOJ 10628. SPOJ COT Count on a tree 可持久化线段树

    这题是裸的主席树,每个节点建一棵主席树,再加个lca就可以了. 历尽艰辛,终于A掉了这一题,这般艰辛也显示出了打代码的不熟练. 错误:1.lca倍增的时候i和j写反了,RE了5次,实在要吸取教训 2. ...

随机推荐

  1. 21、AngularJs知识点总结 part-3

    1.选择框select 在 AngularJS 中我们可以使用 ng-option 指令来创建一个下拉列表,列表项通过对象和数组循环输出,也可以使用ng-repeat 指令来创建下拉列表: 区别:ng ...

  2. android SharedPreferences 浅析

    1. 介绍:SharedPreferences 的作用是使用键值对的方式存储数据.且支持多种不同的数据类型存储: Android数据持久化方法中最简单的一种,即使用Preferences的键值对存储方 ...

  3. CS局域网射击

    2/3D游戏:3D 辅助插件:角色控制器 游戏制作难度系数:中级 用到的其他工具:network 一.解决由于子弹射击速度过快而无法打到物体的问题 //方法一: ; Vector3 originalP ...

  4. jQuery制作table表格布局插件带有列左右拖动效果

    压缩包:http://www.xwcms.net/js/bddm/99004.html

  5. JavaScript里面的基本函数

    1.主要有三类基本函数 <script type="text/javascript"> // 普通函数 function func1(arg){ return true ...

  6. 201621123033 《Java程序设计》第6周学习总结

    第六次作业 1. 本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图或相关笔记,对面向对象思想进行一个总结. 2. 书面作业 1. clone方法 ...

  7. [bzoj4372] 烁烁的游戏 [动态点分治+线段树+容斥原理]

    题面 传送门 思路 观察一下题目,要求的是修改"距离点$u$的距离一定的点权值",那这个就不能用传统的dfs序类算法+线段树维护,因为涉及到向父亲回溯的问题 看到和树上距离相关的东 ...

  8. JZOJ 5279 香港记者

    一句话题意:一个带点权边权的无向图,输出从1号点到n号点的最短路中字典序最小的一条路径 样例输入: 8 9 1 2 3 4 5 6 7 8 1 2 2 2 3 3 3 8 3 1 4 3 4 5 2 ...

  9. [zoj] 1081 Points Within || 判断点是否在多边形内

    原题 多组数据. n为多边形顶点数,m为要判断的点数 按逆时针序给出多边形的点,判断点是否在多边形内,在的话输出"Within",否则输出"Outside" / ...

  10. POJ 3264 Balanced Lineup | st表

    题意: 求区间max-min st表模板 #include<cstdio> #include<algorithm> #include<cstring> #inclu ...