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

题目大意:树上任意两点之间路径中的第k小
解题思路:主席树+LCA

#include<iostream>
#include<cstdio>
#include<vector>
#include<algorithm>
#include<map>
#include<cmath>
#include<set>
#include<cstring>
using namespace std;
typedef long long LL;
const int MAXN=1e5+5;
int n,m,tot;
int cnt,head[MAXN];
int len,root[MAXN],lson[MAXN*20],rson[MAXN*20],val[MAXN*20];
int num,dep[MAXN*2],ver[MAXN*2],fst[MAXN],dp[MAXN*2][20],fa[MAXN];
bool vis[MAXN];
int a[MAXN],b[MAXN];

struct Edge
{
    int to,nxt;
}e[MAXN*2];

void addedge(int u,int v)
{
    e[cnt].to=v;
    e[cnt].nxt=head[u];
    head[u]=cnt++;
}

void build(int l,int r,int &rt)
{
    rt=++tot;
    val[rt]=0;
    if(l==r) return;
    int mid=(l+r)>>1;
    build(l,mid,lson[rt]);
    build(mid+1,r,rson[rt]);
}

void update(int pre,int &rt,int l,int r,int v)
{
    rt=++tot;
    lson[rt]=lson[pre];rson[rt]=rson[pre];val[rt]=val[pre]+1;
    if(l==r) return;
    int mid=(l+r)>>1;
    if(v<=mid) update(lson[pre],lson[rt],l,mid,v);
    else update(rson[pre],rson[rt],mid+1,r,v);
}

void dfs(int u,int fat,int d)
{
    vis[u]=true;ver[++num]=u;dep[num]=d;fst[u]=num;fa[u]=fat;
    update(root[fat],root[u],1,len,a[u]);
    for(int i=head[u];i!=-1;i=e[i].nxt)
    {
        int to=e[i].to;
        if(!vis[to])
        {
            dfs(to,u,d+1);
            ver[++num]=u;dep[num]=d;
        }
    }
}

void ST(int n)
{
    for(int i=1;i<=n;i++) dp[i][0]=i;
    for(int j=1;(1<<j)<=n;j++)
    {
        for(int i=1;i<=n-(1<<j)+1;i++)
        {
            if(dep[dp[i][j-1]]<dep[dp[i+(1<<(j-1))][j-1]])
            dp[i][j]=dp[i][j-1];
            else dp[i][j]=dp[i+(1<<(j-1))][j-1];
        }
    }
}

int RMQ(int l,int r)
{
    int k=log(r-l+1)/log(2);
    if(dep[dp[l][k]]<dep[dp[r-(1<<k)+1][k]]) return dp[l][k];
    else return dp[r-(1<<k)+1][k];
}

int LCA(int u,int v)
{
    u=fst[u],v=fst[v];
    if(u>v) swap(u,v);
    int res=RMQ(u,v);
    return ver[res];
}

int query(int ss,int tt,int lca,int lcafa,int l,int r,int k)
{
    if(l==r) return l;
    int mid=(l+r)>>1;
    int tmp=val[lson[ss]]+val[lson[tt]]-val[lson[lca]]-val[lson[lcafa]];
    if(k<=tmp) return query(lson[ss],lson[tt],lson[lca],lson[lcafa],l,mid,k);
    else return query(rson[ss],rson[tt],rson[lca],rson[lcafa],mid+1,r,k-tmp);
}

int main()
{
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            b[i]=a[i];
        }
        sort(b+1,b+1+n);
        len=unique(b+1,b+1+n)-(b+1);
        for(int i=1;i<=n;i++) a[i]=lower_bound(b+1,b+len+1,a[i])-b;
        cnt=0;
        memset(head,-1,sizeof(head));
        int u,v,k;
        for(int i=1;i<=n-1;i++)
        {
            scanf("%d%d",&u,&v);
            addedge(u,v);addedge(v,u);
        }
        tot=0;
        build(1,len,root[0]);
        num=0;
        memset(vis,false,sizeof(vis));
        dfs(1,0,1);
        ST(2*n-1);
        int lca;
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d%d",&u,&v,&k);
            lca=LCA(u,v);
            printf("%d\n",b[query(root[u],root[v],root[lca],root[fa[lca]],1,len,k)]);
        }
    }
    return 0;
}
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/algzjh/article/details/77507984

智能推荐

计算机器的基本使用_练计算机器-程序员宅基地

文章浏览阅读121次。如何使用cmd命令使用win+R打开运行管理输入cmd 按回车进入编辑界面进入命令界面切换盘符输入 d: 切换到d盘。输入dir命令查看盘符里面的文件新建文件夹使用md 文件名(eg:新建haha文件)在新的文件夹中添加新的文本文档.txt格式的,先切换到文件夹名下使用cd.>1.txt在文本文档中编辑内容使用(echo 内容>文本文档名称)*以上编辑内容属于个人所有,如有雷同纯属巧合。..._练计算机器

链表的使用_在哪里用过链表-程序员宅基地

文章浏览阅读336次。对链表的操作与其他存储结构类似,无非也就是“增删改查”。在这里插入代码片_在哪里用过链表

String类型与Number类型互相转化_string转为number-程序员宅基地

文章浏览阅读2.5w次,点赞2次,收藏4次。Integer类的valueOf方法可以将String转成Number。(非原创,转帖!)下面是代码示例:String numString = “1000″;int id=Integer.valueOf(numString).intValue(); [java] package com.test; public class StringtoInteger { public s..._string转为number

cesium中级(二)获取地形高度_cesium.when-程序员宅基地

文章浏览阅读8.4k次,点赞4次,收藏21次。sampleTerrainMostDetailedsampleTerrainMostDetailed(terrainProvider, positions) → Promise.<Array.<Cartographic>>terrainProvider的类型是TerrainProvider,positions是一个位置的数组,返回的是一个promise,是一个位置数组..._cesium.when

百亿题典之C++编程题面试题_从一个有序数组(由小到大)中删除一个数据。如数组a={1,3,5,7,9},删除3后的a是{1,5-程序员宅基地

文章浏览阅读3.6w次。原文地址:百亿题典之C++编程题面试题作者:百亿题典1. 在linked list中找倒数第N个结点2. 倒转linked list3. 二叉树的结点有指向parent的指针,求最近公共祖先4. 给一个数组,如何打印该数组成员构成集合的全部子集合.5. 有两个字符串,一个是text,一个是command, Command有四种: ‘+’: 在_从一个有序数组(由小到大)中删除一个数据。如数组a={1,3,5,7,9},删除3后的a是{1,5

全局安装 vue_安装全局vue-程序员宅基地

文章浏览阅读1.2w次,点赞5次,收藏3次。通过npm命令安装vuejs 在用 Vue.js 构建大型应用时推荐使用 NPM 安装,NPM 能很好地和诸如Webpack或Browserify的 CommonJS 模块打包器配合使用。(以下操作全在命令行中) 1 2 3 4 # 最新稳定版本 $ npm install -g vue 全局安装 ..._安装全局vue

随便推点

error while loading shared libraries: libcudnn.so.5: cannot open shared object file: No such file or_pmemd.cuda: error while loading shared libraries: -程序员宅基地

文章浏览阅读513次。sudo cp /usr/local/cuda/lib64/libcudnn.so.5 /usr/local/lib/libcudnn.so.5 sudo ldconfig_pmemd.cuda: error while loading shared libraries: libgfortran.so.5: cannot o

使用Keras和Tensorflow设置和安装Mask RCNN_通过keras和tensorflow搭建mask r-cnn-程序员宅基地

文章浏览阅读6.9k次,点赞2次,收藏8次。参考:Github slide: https://github.com/markjay4k/Mask-RCN…Mask RCNN Repo: https://github.com/matterport/Mask_RCNNrequirements.txt: https://github.com/markjay4k/Mask-RCN…Mask RCNN paper: https://arx..._通过keras和tensorflow搭建mask r-cnn

php ab webbance,Apache的ab工具实例详解-程序员宅基地

文章浏览阅读62次。本文主要和大家分享使用Apache的ab工具实例详解,希望能帮助到大家。ab命令原理Apache的ab命令模拟多线程并发请求,测试服务器负载压力,也可以测试nginx、lighthttp、IIS等其它Web服务器的压力。Apache附带的ab工具(使用的PHP环境是WAMP集成环境,ab工具位于D:\wamp\bin\apache\Apache2.2.21\bin)非常容易使用。ab命令对发出负载..._phpab

YY摩登兄弟个唱开办,全网运营成直播平台核心竞争力-程序员宅基地

文章浏览阅读202次。8月17日,网红组合摩登兄弟,在广州“中央车站”举办了一场个人音乐会,座无虚席,个唱主办方是总部同属广州的直播平台YY。摩登兄弟成立于2014年,在2015年3月正式成为YY平台签约主播,在4528频道开播后,凭借着良好的唱功和颜值,快速成长为头部主播,分别获得2016年YY年度组合歌手第4名、2017年YY年度组合歌手第2名。作为平台上的金牌主播,YY对其重视有加,一个细节是,日前的二季度财报分..._摩登兄弟分析其“产品定位、主要内容、变现模式”这几个方面

非线性控制1.1——稳定与跟踪问题概念-程序员宅基地

文章浏览阅读5.5k次,点赞8次,收藏43次。1. 非线性控制系统的两大任务 1.1 稳定(或称调节)问题稳定问题是要使得闭环系统的状态稳定在一个平衡点附近。对于稳定问题,系统的输出不一定要有具体的物理意义,此时可以借助输入-输出状态线性化方法把原非线性熊转换为线性系统,从而用线性系统额理论解决系统的稳定问题。 1.2跟踪(或称伺服)问题跟踪问题是要使得闭环系统的输出跟踪一个给定的时变轨迹。2. 常用的非线性..._非线性控制

Itext7表单域处理(文字和图片)及添加水印_itext7-core 编辑表单域-程序员宅基地

文章浏览阅读9.8k次,点赞6次,收藏24次。Itext7改版相对于Itext5改版很大,由于新出来,很多文档都找不到。最近项目用到,就研究并记录了一下。本文解决的问题:1、替换表单域的变量;2、在表单域位置插入图片,图片根据表单域的大小自动变化;3、添加文字水印,水印显示在图片的上面。程序运行效果如下:1、引入maven依赖包为了方便下面直接引入itext7全家桶,有兴趣可以直接研究单个包引入。<..._itext7-core 编辑表单域

推荐文章

热门文章

相关标签