题解 【POJ3728】The merchant(LCA)
题意:一棵树有N个城市,每个城市商品价格不一样,Q个询问,问从u出发到达v点,每个城市只能经过一次的最大利润
max min数组存u城到u的第2^i个祖先路径上的最值
答案就是u-v路径上的最大值-最小值
真的是这样吗?
仔细想想,买入点可能在卖出点之后吗?当然不行
于是把路径分成两段

问题就变成下列三种情况
购买和卖出都在A段中完成
购买和卖出都在B段中完成
在A段中购买,B段中卖出
然后将A,B段分别进行处理(感觉像是dp的思想)
这还不够,还要分方向进行处理
shun【u】表示从u往LCA走 dao【u】表示从LCA往u走
最后别忘了处理U-LCA购买,LCA-V卖出的情况
#include<cstdio>
#define inf 0x3f3f3f3f
#define N 50005
int n,q,a,b;
int cnt;
int val[N],head[N],dep[N];
int f[N][21],mx[N][21],mn[N][21],shun[N][21],dao[N][21];
void inline swap(int &a,int &b){
a^=b^=a^=b;
}
inline int max(int x,int y){
if(x>y) return x;
return y;
}
inline int min(int x,int y){
if(x<y) return x;
return y;
}
struct node{
int v,nex;
}e[N*2];
inline void add(int u,int v){
cnt++;
e[cnt].v=v;
e[cnt].nex=head[u];
head[u]=cnt;
}
inline void dfs(int u,int fa){
dep[u]=dep[fa]+1;
f[u][0]=fa;
mx[u][0]=max(val[u],val[fa]);
mn[u][0]=min(val[u],val[fa]);
shun[u][0]=max(0,val[fa]-val[u]);
dao[u][0]=max(0,val[u]-val[fa]);
for(register int i=1;i<=20;++i){
f[u][i]=f[f[u][i-1]][i-1];
mx[u][i]=max(mx[u][i-1],mx[f[u][i-1]][i-1]);
mn[u][i]=min(mn[u][i-1],mn[f[u][i-1]][i-1]);
int k=mx[f[u][i-1]][i-1]-mn[u][i-1];
int p=mx[u][i-1]-mn[f[u][i-1]][i-1];
shun[u][i]=max(k,max(shun[u][i-1],shun[f[u][i-1]][i-1]));
dao[u][i]=max(p,max(dao[u][i-1],dao[f[u][i-1]][i-1]));
}
for(register int i=head[u];i;i=e[i].nex){
int v=e[i].v;
if(v==fa) continue;
dfs(v,u);
}
}
inline int lca(int a,int b){
int ans=0,Max=0,Min=0x3f3f3f3f;
Max=val[b],Min=val[a];
if(dep[a]<dep[b]){
for(register int i=20;i>=0;--i){
if(dep[a]>dep[f[b][i]]) continue;
ans=max(ans,max(Max-mn[b][i],dao[b][i]));
Max=max(Max,mx[b][i]);
b=f[b][i];
}
}
else{
for(register int i=20;i>=0;--i){
if(dep[b]>dep[f[a][i]]) continue;
ans=max(ans,max(mx[a][i]-Min,shun[a][i]));
Min=min(Min,mn[a][i]);
a=f[a][i];
}
}
if(a==b) return ans;
for(register int i=20;i>=0;--i){
if(f[b][i]==f[a][i]) continue;
ans=max(ans,max(mx[a][i]-Min,shun[a][i]));
ans=max(ans,max(Max-mn[b][i],dao[b][i]));
Max=max(Max,mx[b][i]);
Min=min(Min,mn[a][i]);
a=f[a][i];
b=f[b][i];
}
ans=max(ans,shun[a][0]);
ans=max(ans,dao[b][0]);
Max=max(Max,mx[b][0]);
Min=min(Min,mn[a][0]);
ans=max(ans,Max-Min);
return ans;
}
int main(){
// freopen("1.in","r",stdin);
// freopen("E.out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;++i){
scanf("%d",&val[i]);
}
for(int i=1;i<n;++i){
scanf("%d%d",&a,&b);
add(a,b);add(b,a);
}
dfs(1,0);
scanf("%d",&q);
for(int i=1;i<=q;++i){
scanf("%d%d",&a,&b);
printf("%d\n",lca(a,b));
}
getchar();
return 0;
}
题解 【POJ3728】The merchant(LCA)的更多相关文章
- POJ3728 THE MERCHANT LCA RMQ DP
题意简述:给定一个N个节点的树,1<=N<=50000 每个节点都有一个权值,代表商品在这个节点的价格.商人从某个节点a移动到节点b,且只能购买并出售一次商品,问最多可以产生多大的利润. ...
- poj3728 倍增法lca 好题!
lca的好题!网上用st表和离线解的比较多,用树上倍增也是可以做的 不知道错在哪里,等刷完了这个专题再回来看 题解链接https://blog.csdn.net/Sd_Invol/article/de ...
- POJ3728 The merchant解题报告
Description There are N cities in a country, and there is one and only one simple path between each ...
- [POJ3728]The merchant
题目大意: 给你一棵n个结点的带权树,有q组询问,问你从u到v的路径上最大值与最小值的差(最大值在最小值后面). 思路: 首先考虑路径上合并两个子路径u->t和t->v时的情况. 假设我们 ...
- poj3728之离线LCA+dp思想/RMQ+LCA(非常好的题目)
题意很简单 给一个树(n < 5w) 每个点有个权值,代表商品价格 若干个询问(5w) 对每个询问,问的是从u点走到v点(简单路径),商人在这个路径中的某点买入商品,然后在某点再卖出商品, ...
- [POJ3728]The merchant(tanrjan_lca + DP)
传送门 比着题解写还错... 查了两个小时没查出来,心态爆炸啊 以后再查 ——代码(WA) #include <cstdio> #include <cstring> #incl ...
- poj3728 The merchant[倍增]
给一棵点带权树,$q$次询问,问树上$x$到$y$路径上,两点权之差(后面的减去前面的)的最大值. 这个是在树链上找点,如果沿路径的最小值在最大值之前出现那肯定答案就是$maxx-minx$,但是反之 ...
- 【BZOJ2588】Count on a tree 题解(主席树+LCA)
前言:其实就是主席树板子啦……只不过变成了树上的查询 -------------------------- 题目链接 题目大意:求树上$u$到$v$路径第$k$大数. 查询静态区间第$k$大肯定是用主 ...
- 【转】Tarjan&LCA题集
转自:http://blog.csdn.net/shahdza/article/details/7779356 [HDU][强连通]:1269 迷宫城堡 判断是否是一个强连通★2767Proving ...
- NOIP2016(D1T2)天天爱跑步题解
首先声明这不是一篇算法独特的题解,仍然是"LCA+桶+树上差分",但这篇题解是为了让很多很多看了很多题解仍然看不懂的朋友们看懂的,其中就包括我,我也在努力地把解题的"思维 ...
随机推荐
- 【随笔记】NDK 编译开源库 nghttp2/openssl/curl
工作中有遇到需要使用支持 http2 访问的 https 安全加密的开源库,便于使用 http2 与云端通信,经过调研发现 libcurl 可以满足需求,但是 libcurl 本身也是需要依赖于 ng ...
- 1888: 生成括号(等级考试3级 2021-09 T5)
题目: 程序: #include<bits/stdc++.h> using namespace std; int n; string s1; void dfs(int l,int r) { ...
- wsl 自动配置代理地址
- Vue02 Node下载安装
转 https://blog.csdn.net/A_awen/article/details/121952701 1 下载 https://nodejs.org/en/download/ 2 安装 全 ...
- 本地python环境安装kylin项目依赖时报认证错误信息
问题描述:项目需要连接kylin数据库查询数据,本地安装kylin项目的依赖环境后报认证错误 python版本3.7 32位 pycharm版本 2022版 成功方法: 更换解释器选择无解释器,创建虚 ...
- Consul+SpringCloud微服务(入门三)
1.安装Consul 我是用的是docker进行安装: 拉取镜像 [root@VM-24-4-centos ~]# docker pull consul Using default tag: late ...
- ROS入门:小海龟实验
1.初试小海龟 1.roscore 2.rosrun turtlesim turtlesim_node 3.rosrun turtlesim turtle_teleop_key 2.发布话题控制小海龟 ...
- 原创ui自动化组件库-seliky
seliky是本人单独开发的一个selenium封装库,非常好用,公司里我所在一整条业务线都用上了噢,可以通过pip来安装,下面简单介绍一下. 一. seliky特性 语法简洁,省去了原生冗长的句式. ...
- Java基础语法:注释、数据类型、字节
Java基础语法:注释.数据类型.字节 注释 单行注释:// 多行注释:/* 注释 */ 文档注释:/** 注释 */ 数据类型分为两大类:基本类型和引用类型 八大基本数据类型 整数类型 byte(占 ...
- redis(13)持久化操作-AOF
AOF(Append Only File) 以日志的形式来记录每个写操作(增量保存),将 Redis 执行过的所有写指令记录下来 (读操作不记录), 只许追加文件但不可以改写文件,redis 启动之初 ...