地址:http://www.spoj.com/problems/COT/en/

题目:

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  思路:  这是一道求树上两点uv路径上的第k大权值的题。
  求第k大很容易想到主席树,但是以前的主席树的都是线性的,这题却是树型的。
  其实只需要把建树的方式改成根据父亲节点建树即可,查询时:sum[u]+sum[v]-sum[lca(u,v)]-sum[fa[lca(u,v)]]。
  这还是一道模板题。
 #include <bits/stdc++.h>

 using namespace std;

 #define MP make_pair
#define PB push_back
typedef long long LL;
typedef pair<int,int> PII;
const double eps=1e-;
const double pi=acos(-1.0);
const int K=2e6+;
const int mod=1e9+; int tot,ls[K],rs[K],rt[K],sum[K];
int v[K],b[K],up[K][],deep[K],fa[K];
vector<int>mp[K];
//sum[o]记录的是该节点区间内出现的数的个数
//区间指的是将数离散化后的区间
void build(int &o,int l,int r)
{
o=++tot,sum[o]=;
int mid=l+r>>;
if(l!=r)
build(ls[o],l,mid),build(rs[o],mid+,r);
}
void update(int &o,int l,int r,int last,int x)
{
o=++tot,sum[o]=sum[last]+;
ls[o]=ls[last],rs[o]=rs[last];
if(l==r) return ;
int mid=l+r>>;
if(x<=mid) update(ls[o],l,mid,ls[last],x);
else update(rs[o],mid+,r,rs[last],x);
}
int query(int ra,int rb,int rc,int rd,int l,int r,int k)
{
if(l==r) return b[l];
int cnt=sum[ls[ra]]+sum[ls[rb]]-sum[ls[rc]]-sum[ls[rd]],mid=l+r>>;
if(k<=cnt) return query(ls[ra],ls[rb],ls[rc],ls[rd],l,mid,k);
return query(rs[ra],rs[rb],rs[rc],rs[rd],mid+,r,k-cnt);
}
void dfs(int x,int f,int sz)
{
update(rt[x],,sz,rt[f],v[x]);
up[x][]=f,deep[x]=deep[f]+,fa[x]=f;
for(int i=;i<=;i++) up[x][i]=up[up[x][i-]][i-];
for(int i=;i<mp[x].size();i++)
if(mp[x][i]!=f)
dfs(mp[x][i],x,sz);
}
int lca(int x,int y)
{
if(deep[x]<deep[y]) swap(x,y);
for(int i=;i>=;i--) if( deep[up[x][i]]>=deep[y]) x=up[x][i];
if(x==y) return x;
for(int i=;i>=;i--) if(up[x][i]!=up[y][i]) x=up[x][i],y=up[y][i];
return up[x][];
}
int main(void)
{
tot=;
int n,m,sz;
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
scanf("%d",v+i),b[i]=v[i];
for(int i=,x,y;i<n;i++)
scanf("%d%d",&x,&y),mp[x].PB(y),mp[y].PB(x);
sort(b+,b++n);
sz=unique(b+,b++n)-b-;
for(int i=;i<=n;i++)
v[i]=lower_bound(b+,b++sz,v[i])-b;
build(rt[],,sz);
dfs(,,sz);
int x,y,k;
while(m--)
scanf("%d%d%d",&x,&y,&k),printf("%d\n",query(rt[x],rt[y],rt[lca(x,y)],rt[fa[lca(x,y)]],,sz,k));
return ;
}

SPOJ - COT Count on a tree的更多相关文章

  1. spoj cot: Count on a tree 主席树

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

  2. spoj COT - Count on a tree (树上第K小 LCA+主席树)

    链接: https://www.spoj.com/problems/COT/en/ 思路: 首先看到求两点之前的第k小很容易想到用主席树去写,但是主席树处理的是线性结构,而这道题要求的是树形结构,我们 ...

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

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

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

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

  5. spoj COT - Count on a tree(主席树 +lca,树上第K大)

    您将获得一个包含N个节点的树.树节点的编号从1到Ñ.每个节点都有一个整数权重. 我们会要求您执行以下操作: uvk:询问从节点u到节点v的路径上的第k个最小权重 输入 在第一行中有两个整数Ñ和中号.( ...

  6. SPOJ 10628 COT - Count on a tree(在树上建立主席树)(LCA)

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

  7. SPOJ 10628 Count on a tree(Tarjan离线LCA+主席树求树上第K小)

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

  8. SPOJ 10628 Count on a tree(Tarjan离线 | RMQ-ST在线求LCA+主席树求树上第K小)

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

  9. BZOJ 2588: Spoj 10628. Count on a tree [树上主席树]

    2588: Spoj 10628. Count on a tree Time Limit: 12 Sec  Memory Limit: 128 MBSubmit: 5217  Solved: 1233 ...

随机推荐

  1. 插件之下拉框Select2

    select2为代替常规的select而出现,可自定义select的样式,最明显的功能就是集合中可以搜索 关于浏览器要求,ie8+,Chrome 8+,Firefox 10+,Safari 3+,Op ...

  2. jQuery实用技巧必备

    本文实例总结了经典且实用的jQuery代码开发技巧.分享给大家供大家参考.具体如下: 1. 禁止右键点击 $(document).ready(function(){  $(document).bind ...

  3. VC++ 设置桌面壁纸

    Windows Shell API提供了接口IActiveDesktop来完成墙纸的设置. //IActiveDesktop 接口方法表 (详情参见MSDN) AddDesktopItem AddDe ...

  4. Oracle的优化器的RBO和CBO方式

      1.基于规则的优化方式(Rule-Based Optimization,简称为RBO)       优化器在分析SQL语句时,所遵循的是Oracle内部预定的一些规则,对数据是不敏感的.它只借助少 ...

  5. 88、android 插件开发教程(转载)

    http://blog.csdn.net/qq435757399/article/details/46521085 http://blog.csdn.net/t12x3456/article/deta ...

  6. height:calc(100% - 40px)

    在移动端开发的过程中,常常会遇到头部高度是40px,而内容页是除去头部,占满视窗的整个高度,有时候是用js来处理,现在用css的calc是非常方便的: .container{ height: calc ...

  7. 《从零开始学Swift》学习笔记(Day 66)——Cocoa Touch设计模式及应用之通知机制

    原创文章,欢迎转载.转载请注明:关东升的博客 通知(Notification)机制是基于观察者(Observer)模式也叫发布/订阅(Publish/Subscribe)模式,是 MVC( 模型-视图 ...

  8. Chrome浏览器断点调试无效的问题

    问题是这样的,在使用chrome浏览器调试JavaScript的时候,突然设置的断点失效了,怎么弄都没有效果. 折腾了半天,尝试了各种方法就是没有用. 解决:重启一下chrome浏览器就好了,这似乎是 ...

  9. Java+selenium+Fitnesse

    刚开始接触selenium是进公司后,老大给我们培训了一下UI自动化(其实也不叫培训啦,就是让我们知道有这么个东西吧,我这么说,老大看到得打人了,哈哈).要进行自动化测试,当然就得搭建一个自动化测试框 ...

  10. Spoken English Practice(Don't get me wrong, that explanation makes no difference, I'm still mad at you. Come on, be reasonable!)

    绿色:连读:                  红色:略读:               蓝色:浊化:               橙色:弱读     下划线_为浊化 口语蜕变(2017/7/11) ...