[hdu3078]Network(LCA+排序)
题意:维护树上两点之间的最短路径,其一,将点a的值变为b,其二,求路径上第k大的值。
解题关键:LCA+sort
复杂度:$O(qn\log n + n\log n)$ 数据弱不怪我
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<vector>
typedef long long ll;
using namespace std;
const int maxn=;
const int maxm=;
int _pow[maxm],m,n;
int head[maxn],tot;
int ver[maxn*],depth[maxn*],first[maxn],rmq[maxn*][],id;//5个数组,注意哪个需要乘2
int pre[maxn],val[maxn];
inline int read(){
char k=;char ls;ls=getchar();for(;ls<''||ls>'';k=ls,ls=getchar());
int x=;for(;ls>=''&&ls<='';ls=getchar())x=(x<<)+(x<<)+ls-'';
if(k=='-')x=-x;return x;
} struct edge{
int to,nxt;
}e[maxn*];//链式前向星建树 void init(){
memset(head,-,sizeof head);
tot=;
id=;
} void add_edge(int u,int v){
e[tot].to=v;
e[tot].nxt=head[u];
head[u]=tot++;
} void dfs(int u,int fa,int dep){
ver[++id]=u;//第i个访问到的结点编号
depth[id]=dep;//第i个访问到的结点深度
first[u]=id;
for(int i=head[u];i!=-;i=e[i].nxt){
int v=e[i].to;
if(v==fa) continue;
pre[v]=u;
dfs(v,u,dep+);
ver[++id]=u;//后序遍历,再次访问父节点
depth[id]=dep;
}
} void rmq_init(int n){
int k=int(log(n)/log());
for(int i=;i<=n;++i) rmq[i][]=i;
for(int j=;j<=k;++j){
for(int i=;i+_pow[j]-<=n;++i){//因为存的是索引
int a=rmq[i][j-],b=rmq[i+_pow[j-]][j-];
rmq[i][j]=depth[a]<depth[b]?a:b;
}
}
} int rmq_query(int l,int r){
int k=int(log(r-l+1.0)/log(2.0));
int a=rmq[l][k],b=rmq[r-_pow[k]+][k];
return depth[a]<depth[b]?a:b;
}//返回的依然是索引 int LCA(int u,int v){
int x=first[u],y=first[v];
if(x>y)swap(x,y);
int res=rmq_query(x,y);
return ver[res];
} vector<int>path;
//int path[maxn];
void solve(int k,int a,int b){
//int cnt=0;
path.clear();
int lca=LCA(a,b);
while(b!=lca) path.push_back(val[b]),b=pre[b];
while(a!=lca) path.push_back(val[a]),a=pre[a];
path.push_back(val[lca]);
if(path.size()<k){
printf("invalid request!\n");
return;
}
sort(path.begin(),path.end(),greater<int>());
printf("%d\n",path[k-]);
return;
} int main(){
for(int i=;i<maxm;++i) _pow[i]=<<i; //预处理2^n
int k,a,b;
n=read();m=read();
init();
for(int i=;i<=n;i++) val[i]=read();
for(int i=;i<n-;++i){
a=read(),b=read();
add_edge(a,b);
add_edge(b,a);
}
dfs(,-,);
rmq_init(*n-);
for(int i=;i<m;++i){
k=read();a=read();b=read();
if(k) solve(k,a,b);
else val[a]=b;
} return ;
}
[hdu3078]Network(LCA+排序)的更多相关文章
- hdu-3078 Network(lca+st算法+dfs)
题目链接: Network Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) P ...
- HDU 3078 Network(LCA dfs)
Network [题目链接]Network [题目类型]LCA dfs &题意: 给出n个点的权值,m条边,2种操作 0 u num,将第u个点的权值改成num k u v,询问u到v这条路上 ...
- Network LCA修改点权
Problem Description The ALPC company is now working on his own network system, which is connecting a ...
- HDU3078 Network [2016年6月计划 树上问题05]
Network Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Sub ...
- Network(lca暴力)
Network Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/65536K (Java/Other) Total Submi ...
- hdu3078 伪LCA……
题意:有 n 点的一颗树,每个节点有格子的权值,现在有两种操作,修改一个点的权值,或者求两点之间的路径上的第 k 大的权值. 其实看到这个题,就在 YY 各种做法,询问后得到貌似可能是关于主席树.树链 ...
- HDU 3078 Network LCA
题意:n个点 m个询问,下面一行是n 个点的权值 再下面n-1行是双向的边 然后m个询问:k u v 若k==0,则把u点的权值改为v,否则回答u->v之间最短路经过点的权值中 第k大的值是多 ...
- [poj3417]Network(LCA+树形dp)
题意:给出一棵无根树,然后下面再给出m条边,把这m条边连上,每次你去两条边,规定一条是树边,一条是新边,问有多少种方案能使树断裂. 解题关键:边权转化为点权,记录每条边被环覆盖的次数,通过val[a] ...
- poj3417 Network——LCA+树上差分
题目:http://poj.org/problem?id=3417 根据一条边被几个环覆盖来判断能不能删.有几种情况等: 用树上差分,终点 s++,LCA s-=2,统计时计算子树s值的和即可: 用S ...
随机推荐
- Process Stats:了解你的APP怎样使用内存
原文地址:http://android-developers.blogspot.com/2014/01/process-stats-understanding-how-your.html?m=1 原作 ...
- Python 爬虫常见的坑和解决方法
1.请求时出现HTTP Error 403: Forbidden headers = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:23. ...
- Android UI开发第四十三篇——使用Property Animation实现墨迹天气3.0引导界面及动画实现
前面写过<墨迹天气3.0引导界面及动画实现>,里面完美实现了动画效果,那一篇文章使用的View Animation,这一篇文章使用的Property Animation实现.Propert ...
- c# 根据枚举Value 获得名称
// 定义枚举类型enum sotype : int { book=1, pen=2, other=3 } // 输出名称 switch (Enum.GetName(typeof(sotype), 1 ...
- tps 与 事务平均响应时间关系对答(转)
问者:每秒处理的事务数和事务的平均响应时间 怎么个关系,有关系吗 kaku21:举个例子:一个高速路 有10个入口,每个入口每秒钟只能进1辆车,请问1秒钟最多能进几辆车?? 问者:10 kaku21: ...
- 用于string对象中字符截取的几种函数总结——语法、参数意义及用途举例
1. charAt():返回指定位置的字符. 语法:stringObject.charAt(index) 参数意义:index 必需,指字符在字符串中的下标.需要注意的是,字符串中第一个字符的下标是 ...
- 我的Android进阶之旅------>温习Sqlite3的常用操作
前言;今天要写一个应用来调节系统的Brightness值,来改变系统的背光亮度.由于刚开始些的时候没有考虑Brightness的最小值,直接托动SeekBar到最小值(为0).瞬间,屏幕变成全黑,失败 ...
- Mysql 外键级联
如果表A的主关键字是表B中的字段,则该字段称为表B的外键,表A称为主表,表B称为从表.外键是用来实现参照完整性的,不同的外键约束方式将可以使两张表紧密的结合起来,特别是修改或者删除的级联操作将使得日常 ...
- ubuntu安装opencv(自己编译)
如果只需要python的,只需pip install opencv-python,然后apt-get一下下面第一点的东东. 1/ sudo apt-get install build-essentia ...
- LeetCode:访问所有节点的最短路径【847】
LeetCode:访问所有节点的最短路径[847] 题目描述 给出 graph 为有 N 个节点(编号为 0, 1, 2, ..., N-1)的无向连通图. graph.length = N,且只有节 ...