题意:

n个点 m个询问

下面n个数字表示点权值

n-1行给定一棵树

m个询问 k u v

k为0时把u点权值改为v

或者问 u-v的路径上 第k大的数

思路:

LCA转RMQ求出 LCA(u,v) ;

登山坡式找到路径上所有点并记录其权值

排序输出k大的数

#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string>
#include<queue>
#include<string.h>
#include<map>
#include<set>
#include<stack>
#include<vector>
#include<math.h>
#define N 80010
using namespace std;
inline int Max(int a,int b){return a>b?a:b;} struct node{
int from, to, nex;
}edge[N<<1];
int head[N], edgenum;
void addedge(int u, int v){
node E = {u, v, head[u]};
edge[ edgenum ] = E;
head[u] = edgenum ++;
}
int val[N], Stack[N]; int time;
int deep[N<<1], index[N<<1], first[N], pre[N];
void DFS(int u, int dep){
deep[time] = u;
index[time] =u;
time++;
for(int i = head[u]; i !=-1; i = edge[i].nex)
{
int v = edge[i].to;
if(first[v] == 0)
{
first[v] = time;
pre[v] = u;
DFS(v, dep+1);
deep[time] = u;
index[time]= u;
time++;
}
}
}
int dp[N<<1][25];
void RMQ_init(int n){
for(int i = 1; i <= n; i++)
dp[i][0] = i;
for(int j = 1; (1<<j)<=n;j++)
{
int k = 1<<(j-1);
for(int i = 1; i+k<n; i++)
{
if(deep[ dp[i][j-1] ] <= deep[ dp[i+k][j-1] ])
dp[i][j] = dp[i][j-1];
else
dp[i][j] = dp[i+k][j-1];
}
}
}
int RMQ(int a,int b){
int dis = Max(a-b,b-a) +1;
int k = log(double(dis))/ log(2.0);
if(deep[dp[a][k]]<= deep[dp[b - (1<<k) +1][k]])
return dp[a][k];
else
return dp[b-(1<<k)+1][k];
}
int LCA(int u, int v){
int fu = first[u], fv = first[v];
return fu<=fv? index[ RMQ(fu,fv)] : index[ RMQ(fv,fu)];
} int main()
{
int n, m, i, j, k, que, u, v;
int root = 1;
while(~scanf("%d%d",&n,&que))
{
memset(head, -1, sizeof(head)); edgenum = 0;
memset(first, 0, sizeof(first)); for(i=1;i<=n;i++)scanf("%d",&val[i]);
for(i=1;i<n;i++)
{
scanf("%d %d",&u,&v);
addedge(u, v); addedge(v, u);
}
first[root] = 1;
time = 1;
DFS(root, 0);
RMQ_init(time-1);
while(que--){
scanf("%d %d %d",&k,&u,&v);
if(k==0)
{val[u] = v; continue;}
if(u==v){
if(k==1)printf("%d\n",val[u]);
else printf("invalid request!\n");continue;
}
int c = LCA(u, v);
int top = 0;
Stack[top++] = val[c];
while(u!=c)
{
Stack[top++] = val[u];
u = pre[u];
}
while(v!=c)
{
Stack[top++] = val[v];
v = pre[v];
}
if(top<k)
{printf("invalid request!\n");continue;}
sort(Stack, Stack+top);
printf("%d\n",Stack[top - k]);
}
}
return 0;
}
8 99
5 2 3 4 5 6 7 8
1 3
1 2
3 4
3 5
5 6
5 7
7 8
1 2 8
2 2 8
3 2 8
4 2 8
5 2 8
6 2 8
7 2 8
1 4 8
4 2 3
5 3 8
2 3 8
0 3 8
2 3 8
3 3 8
2 4 5
1 4 1
2 4 1
3 4 1 ans:
8
7
5
5
3
2
in...
8
in...
in...
7
8
7
5
8
5
4 1 1
5
1 1 1 ans:
5 2 2
2 1
1 2
2 2 1
1 1 2 ans:
1
2

HDU 3078 LCA转RMQ的更多相关文章

  1. HDU 3078 (LCA+树链第K大)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3078 题目大意:定点修改.查询树中任意一条树链上,第K大值. 解题思路: 先用离线Tarjan把每个 ...

  2. hdu 3078(LCA的在线算法)

    Network Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Sub ...

  3. hdu 3078 Network (暴力)+【LCA】

    <题目链接> 题目大意:给定一颗带点权的树,进行两种操作,k=0,更改某一点的点权,k!=0,输出a~b路径之间权值第k大的点的点权. 解题分析:先通过RMQ的初始化,预处理pre[]数组 ...

  4. LCA和RMQ

    下面写提供几个学习LCA和RMQ的博客,都很通熟易懂 http://dongxicheng.org/structure/lca-rmq/ 这个应该是讲得最好的,且博主还有很多其他文章,可以读读,感觉认 ...

  5. ZOJ 3195 Design the city LCA转RMQ

    题意:给定n个点,下面n-1行 u , v ,dis 表示一条无向边和边权值,这里给了一颗无向树 下面m表示m个询问,问 u v n 三点最短距离 典型的LCA转RMQ #include<std ...

  6. [CF 191C]Fools and Roads[LCA Tarjan算法][LCA 与 RMQ问题的转化][LCA ST算法]

    参考: 1. 郭华阳 - 算法合集之<RMQ与LCA问题>. 讲得很清楚! 2. http://www.cnblogs.com/lazycal/archive/2012/08/11/263 ...

  7. hdu 4123 树形DP+RMQ

    http://acm.hdu.edu.cn/showproblem.php? pid=4123 Problem Description Bob wants to hold a race to enco ...

  8. lca转RMQ

    这个博客写得好 #include <stdio.h> #include <vector> #include <string.h> using namespace s ...

  9. 【51NOD1766】树上的最远点对(线段树,LCA,RMQ)

    题意:n个点被n-1条边连接成了一颗树,给出a~b和c~d两个区间, 表示点的标号请你求出两个区间内各选一点之间的最大距离,即你需要求出max{dis(i,j) |a<=i<=b,c< ...

随机推荐

  1. PHP——explode的应用(获取字符串,拆为下拉列表)

    <?php //定义有默认值的函数 function Main3($f=5,$g=6) { echo $f*$g; } Main3(2,3); echo "<br />&q ...

  2. js 立即执行函数

    1.我们首先要搞明白:函数表达式和函数声明的区别. 函数表达式:既可以为匿名函数也可以有函数名,但是调用的时候都是通过函数左边的变量func来调用 var func = function(){ ale ...

  3. 引爆你的Javascript代码进化

    转自:http://www.hicss.net/evolve-your-javascript-code/ 方才在程序里看到一段JS代码,写法极为高明,私心想着若是其按照规范来写,定可培养对这门语言的理 ...

  4. Java 线程池 Executor 框架

    在Java中,可以通过new Thread 的方法来创建一个新的线程执行任务,但是线程的创建是非常耗时的,而且创建出来的新的线程都各自运行.缺乏统一的管理,这样的后果是可能导致创建过多的线程从而过度消 ...

  5. RabbitVCS - Ubuntu VCS Graphical Client

    Easy version control for Linux RabbitVCS is a set of graphical tools written to provide simple and s ...

  6. laravel错误1071 Specified key was too long; max key length is 1000 bytes

    Laravel 5.5 环境,php artisan migrate 之后,出现错误如题. 检查了一下,代码是这样的: $table->increments('id'); $table-> ...

  7. 校园网ipv6连接问题

    没有ipv6的信号:只需要进入网络适配器里面先禁用再启用即可.

  8. 堆和索引堆的实现(python)

    ''' 索引堆 ''' ''' 实现使用2个辅助数组来做.有点像dat.用哈希表来做修改不行,只是能找到这个索引,而需要change操作 还是需要自己手动写.所以只能用双数组实现. #引入索引堆的核心 ...

  9. PDO beginTransaction (),exec(),commit ()

    $dsn = 'sqlsrv:server=.\SQLExpress;Database=thinkphp'; $user = 'admin'; $password = 'pass1234'; try ...

  10. 通用Mapper

    原理是:拦截器 1.假设:使用MyBatis只需要定义Mapper接口,无需编写Mapper.xml文件 如果实现无需编写Mapper.xml文件,我们必须要实现动态拼接SQL 如何实现动态拼接SQL ...