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. 如何自己编译apue.3e中代码 & 学习写makefile

    本来是搜pthread的相关资料,看blog发现很多linux程序员都看的一本神书<APUE>,里面有系统的两章内容专门讲pthread(不过是用c语言做的代码示例,这个不碍事,还是归到原 ...

  2. RPG游戏黑暗之光

    1.设置默认鼠标光标 PlayerSettings → Default Cursor 下设置 2.为人物创建单一类 为人物创建了PlayerAnimation.cs.PlayerDir.cs.Play ...

  3. 构建Docker镜像两种方式的比较-Dockerfile方式和S2I方式

    前言 写Dockerfile是构建Docker镜像最通常的方式,接触过Docker的童鞋多少了解一些.前段时间研究OpenShift(paas的一种),发现了另外一种构建Docker镜像的方式:S2I ...

  4. 博客挪窝了 http://my.oschina.net/jrrx/blog

    1. 博客园很不错: 2. 由于各种原因,挪到了 http://my.oschina.net/jrrx/blog

  5. 七、LSP 里氏替换原则

    子类的对象提供了父类的所有行为,且加上子类额外的一些东西(可以是功能,可以是属性).当程序基于父类实现时,如果将子类替换父类而程序不需修改,则说明符合LSP原则. 这个解释看的似懂非懂,再看下面更进一 ...

  6. iis如何处理并发请求

    文章:IIS是怎么处理同时到来的多个请求的? 文章:你真的了解:IIS连接数.IIS并发连接数.IIS最大并发工作线程数.应用程序池的队列长度.应用程序池的... 文章:IIS最大工作进程数设置引发串 ...

  7. FormsAuthentication类

    理解代码: string cookieName = FormsAuthentication.FormsCookieName; FormsAuthentication类说明: // 摘要: // 为 W ...

  8. 【Python】- 第一行跟第二行的写法

    第一行:目的就是指出,你想要你的这个文件中的代码用什么可执行程序去运行它,就这么简单 #!/usr/bin/python:告诉操作系统执行这个脚本的时候,调用/usr/bin下的python解释器: ...

  9. HTML5_纯JS实现上传文件显示文件大小,文件信息,上传进度_不使用JS库

    前台 html <input type="file" id="_netLogo" onchange="fileSelected();" ...

  10. 【bzoj4419】[Shoi2013]发微博 STL-set

    题目描述 刚开通的SH微博共有n个用户(1..n标号),在短短一个月的时间内,用户们活动频繁,共有m条按时间顺序的记录: ! x   表示用户x发了一条微博: + x y 表示用户x和用户y成为了好友 ...