<题目链接>

题目大意:
给定一颗带点权的树,进行两种操作,k=0,更改某一点的点权,k!=0,输出a~b路径之间权值第k大的点的点权。

解题分析:
先通过RMQ的初始化,预处理pre[]数组,并且求出a和b的LCA。然后利用LCA将a、b路径上所有点的点权全部存储起来,将其排序,就可得到a、b路径上权值第k大的点权。具体操作为:利用pre[]数组,从a到LCA的所有点权全部相加,然后再将从b到LCA的所有点权相加,就可以得到a、b路径上所有点的点权。下面用的是LCA转RMQ的方法求解。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std; const int maxn = 8e4+;
struct Edge{
int to,next;
}edge[maxn<<];
int n,q,cnt,num,tot,pre[maxn],val[maxn],fa[maxn];
int st[maxn<<][],ver[maxn<<],dep[maxn<<],first[maxn],path[maxn]; bool cmp(int a,int b){ return a > b;}
int Min(int l,int r){
return dep[l]<dep[r]?l:r;
}
void addedge(int u,int v){
edge[num].to = v,edge[num].next = pre[u];
pre[u] = num++;
}
void dfs(int u,int deep){
ver[++cnt] = u; first[u] = cnt; dep[cnt] = deep;
for(int i = pre[u]; i != -; i = edge[i].next){
int v = edge[i].to;
if(fa[u] == v) continue;
fa[v] = u;
dfs(v,deep+);
ver[++cnt] = u; dep[cnt] = deep;
}
}
void RMQ_init(){
for(int i = ; i <= cnt; i++)
st[i][] = i;
for(int j = ; ( << j) <= cnt; j++)
for(int i = ; i + ( << j) < cnt; i++)
st[i][j] = Min(st[i][j-],st[i+(<<(j-))][j-]);
}
int findLCA(int l,int r){
int k = (int)(log(r - l + 1.0) / log(2.0));
return ver[Min(st[l][k],st[r-(<<k)+][k])];
}
//以上是LCA转RMQ的模板
int main(){
int k,a,b;
while(scanf("%d%d",&n,&q)!=EOF){
cnt = num = ;
memset(pre,-,sizeof(pre));
for(int i = ; i <= n; i++)
scanf("%d",&val[i]);
for(int i = ; i < n; i++){
scanf("%d%d",&a,&b);
addedge(a,b);
addedge(b,a);
}
dfs(,);
RMQ_init();
while(q--){
scanf("%d%d%d",&k,&a,&b);
if(k == )val[a] = b;
else{
int x = first[a], y = first[b];
if(x > y) swap(x,y);
int lca = findLCA(x,y); //得到最近公共祖先
tot = ;
while(a != lca){ //将a到最近公共祖先的路劲上所有的点权放入path数组
path[++tot] = val[a];
a = fa[a];
}
while(b != lca){ //将a到最近公共祖先的路劲上所有的点权放入path数组
path[++tot] = val[b];
b = fa[b];
}
path[++tot] = val[lca]; //再加上lca的点权
if(k > tot) printf("invalid request!\n");
else{
sort(path+,path++tot,cmp); //将a->b路劲上所有点权排序,然后就可以得到第k大的点权
printf("%d\n",path[k]);
}
}
}
}
return ;
}

2018-10-23

hdu 3078 Network (暴力)+【LCA】的更多相关文章

  1. HDU - 3078 Network(暴力+LCA)

    题目大意:给出n个点的权值.m条边,2种操作 0 u num,将第u个点的权值改成num k u v,询问u到v这条路上第k大的权值点 解题思路:该点的话直接该,找第k大的话直接暴力 #include ...

  2. HDU 3078 Network(LCA dfs)

    Network [题目链接]Network [题目类型]LCA dfs &题意: 给出n个点的权值,m条边,2种操作 0 u num,将第u个点的权值改成num k u v,询问u到v这条路上 ...

  3. HDU 3078 Network LCA

    题意:n个点 m个询问,下面一行是n 个点的权值 再下面n-1行是双向的边 然后m个询问:k u v 若k==0,则把u点的权值改为v,否则回答u->v之间最短路经过点的权值中  第k大的值是多 ...

  4. HDU 3078 Network

    简单的  RMQ:  先预处理得到  所有 节点的 公共祖先  和  dfs 得到所有节点的父亲节点:  然后  询问时,从自己出发向上找父亲, 然后  得到所有的节点:排序一下 不知道  这题这样也 ...

  5. HDU 2460 Network(双连通+树链剖分+线段树)

    HDU 2460 Network 题目链接 题意:给定一个无向图,问每次增加一条边,问个图中还剩多少桥 思路:先双连通缩点,然后形成一棵树,每次增加一条边,相当于询问这两点路径上有多少条边,这个用树链 ...

  6. poj 3417 Network(tarjan lca)

    poj 3417 Network(tarjan lca) 先给出一棵无根树,然后下面再给出m条边,把这m条边连上,然后每次你能毁掉两条边,规定一条是树边,一条是新边,问有多少种方案能使树断裂. 我们设 ...

  7. HDU 3078:Network(LCA之tarjan)

    http://acm.hdu.edu.cn/showproblem.php?pid=3078 题意:给出n个点n-1条边m个询问,每个点有个权值,询问中有k,u,v,当k = 0的情况是将u的权值修改 ...

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

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

  9. HDU 2460 Network(桥+LCA)

    http://acm.hdu.edu.cn/showproblem.php?pid=2460 题意:给出图,求每次增加一条边后图中桥的数量. 思路: 先用tarjan算法找出图中所有的桥,如果lowv ...

随机推荐

  1. Confluence 6 配置服务器基础地址

    服务器基础地址(Server Base URL)是用户访问 Confluence 的 URL 地址.这个基础的 URL 地址必须与你在浏览器中访问 Confluence 中的地址. Confluenc ...

  2. Confluence 6 CSS 指南:修改顶部背景

    Confluence 默认页面的顶部是有关站点的菜单连接,在这里定义了 快速连接, 浏览菜单,用户菜单和快速查找输入框.在这个示例中,我们将会尝试修改顶部的菜单部分的背景和一些自定义的图片. 创建一个 ...

  3. java----static关键字(包括final)

    static修饰字段: 使用static关键字修饰一个字段:声明的static变量实际上就是一个全局变量 使用static关键字修饰一个方法:可以直接使用类调用方法,和对象没有关系了 使用static ...

  4. requests中get和post传参

    get请求 get(url, params=None, **kwargs) requests实现get请求传参的两种方式 方式一: import requests url = 'http://www. ...

  5. C++ StrCat()

    关于StrCat function,参考:https://msdn.microsoft.com/en-us/library/windows/desktop/bb759925(v=vs.85).aspx ...

  6. sass基础—具体编译步骤及对应命令:详细

    /*基础语法*/h1{ color: red;} /*变量定义*/ $color: red; /*嵌套*/body{ header{ } footer{ }} /*mixin函数*/@mixin al ...

  7. spring cloud 使用ribbon简单处理客户端负载均衡

    假如我们的multiple服务的访问量剧增,用一个服务已经无法承载, 我们可以把Hello World服务做成一个集群. 很简单,我们只需要复制Hello world服务,同时将原来的端口8762修改 ...

  8. python 装饰器(1)

    # 装饰器,对一个函数打扮 # def foo():# print("foo")# foo# foo()# def test1():# print('-----1-----')# ...

  9. C++11 中的function和bind、lambda用法

    std::function 1. std::bind绑定一个成员函数 #include <iostream> #include <functional> struct Foo ...

  10. Go语言之匿名函数

    匿名函数和字面量函数一样, 凡是可以使用字面量函数的地方,都可以用匿名函数代替. 这个和js中的匿名函数差不多吧. package main import "fmt" var su ...