题目大意:
  给你一棵n个结点的带权树,有q组询问,问你从u到v的路径上最大值与最小值的差(最大值在最小值后面)。

思路:
  首先考虑路径上合并两个子路径u->t和t->v时的情况。
  假设我们已经知道了两个路径的最大值max,最小值min,以及路径上最大值与最小值的差d(最大值在最小值后面),
  那么我们最大值和最小值可以直接合并,d=max(d1,d2,max2-max1)。
  现在我们用倍增或者树链剖分维护这些东西,再跑一跑LCA即可。
  然而我们发现往上跑和往下跑是不一样的,所以我们要维护两种差值up和down,一种是最大值在最小值上,一种是最小值在最大值上。

 #include<cstdio>
#include<cctype>
#include<vector>
inline int getint() {
register char ch;
while(!isdigit(ch=getchar()));
register int x=ch^'';
while(isdigit(ch=getchar())) x=(((x<<)+x)<<)+(ch^'');
return x;
}
const int inf=0x7fffffff;
const int N=,logN=;
int w[N];
std::vector<int> e[N];
inline void add_edge(const int &u,const int &v) {
e[u].push_back(v);
e[v].push_back(u);
}
inline int log2(const float &x) {
return ((unsigned&)x>>&)-;
}
int dep[N],anc[N][logN],max[N][logN],min[N][logN],up[N][logN],down[N][logN];
void dfs(const int &x,const int &par) {
dep[x]=dep[par]+;
anc[x][]=par;
max[x][]=std::max(w[x],w[par]);
min[x][]=std::min(w[x],w[par]);
up[x][]=std::max(w[par]-w[x],);
down[x][]=std::max(w[x]-w[par],);
for(register int i=;i<=log2(dep[x]);i++) {
anc[x][i]=anc[anc[x][i-]][i-];
max[x][i]=std::max(max[x][i-],max[anc[x][i-]][i-]);
min[x][i]=std::min(min[x][i-],min[anc[x][i-]][i-]);
up[x][i]=std::max(std::max(up[x][i-],up[anc[x][i-]][i-]),max[anc[x][i-]][i-]-min[x][i-]);
down[x][i]=std::max(std::max(down[x][i-],down[anc[x][i-]][i-]),max[x][i-]-min[anc[x][i-]][i-]);
}
for(unsigned i=;i<e[x].size();i++) {
const int &y=e[x][i];
if(y==par) continue;
dfs(y,x);
}
}
inline int lca(int x,int y) {
if(dep[x]<dep[y]) std::swap(x,y);
for(register int i=log2(dep[x]);i>=;i--) {
if(dep[anc[x][i]]>=dep[y]) {
x=anc[x][i];
}
}
if(x==y) return x;
for(register int i=log2(dep[x]);i>=;i--) {
if(anc[x][i]!=anc[y][i]) {
x=anc[x][i];
y=anc[y][i];
}
}
return anc[x][];
}
inline int solve(int x,int y) {
const int t=lca(x,y);
int pmaxup=,pminup=inf,pmaxdown=,pmindown=inf,pup=,pdown=;
for(register int i=log2(dep[x]);i>=;i--) {
if(dep[anc[x][i]]>=dep[t]) {
pup=std::max(std::max(pup,up[x][i]),max[x][i]-pminup);
pmaxup=std::max(pmaxup,max[x][i]);
pminup=std::min(pminup,min[x][i]);
x=anc[x][i];
}
}
for(register int i=log2(dep[y]);i>=;i--) {
if(dep[anc[y][i]]>=dep[t]) {
pdown=std::max(std::max(pdown,down[y][i]),pmaxdown-min[y][i]);
pmaxdown=std::max(pmaxdown,max[y][i]);
pmindown=std::min(pmindown,min[y][i]);
y=anc[y][i];
}
}
return std::max(std::max(pup,pdown),pmaxdown-pminup);
}
int main() {
int n=getint();
for(register int i=;i<=n;i++) {
w[i]=getint();
}
for(register int i=;i<n;i++) {
add_edge(getint(),getint());
}
dfs(,);
for(register int q=getint();q;q--) {
const int u=getint(),v=getint();
printf("%d\n",solve(u,v));
}
return ;
}

[POJ3728]The merchant的更多相关文章

  1. POJ3728 The merchant解题报告

    Description There are N cities in a country, and there is one and only one simple path between each ...

  2. [POJ3728]The merchant(tanrjan_lca + DP)

    传送门 比着题解写还错... 查了两个小时没查出来,心态爆炸啊 以后再查 ——代码(WA) #include <cstdio> #include <cstring> #incl ...

  3. POJ3728 THE MERCHANT LCA RMQ DP

    题意简述:给定一个N个节点的树,1<=N<=50000 每个节点都有一个权值,代表商品在这个节点的价格.商人从某个节点a移动到节点b,且只能购买并出售一次商品,问最多可以产生多大的利润. ...

  4. poj3728 The merchant[倍增]

    给一棵点带权树,$q$次询问,问树上$x$到$y$路径上,两点权之差(后面的减去前面的)的最大值. 这个是在树链上找点,如果沿路径的最小值在最大值之前出现那肯定答案就是$maxx-minx$,但是反之 ...

  5. [最近公共祖先] POJ 3728 The merchant

    The merchant Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 4556   Accepted: 1576 Desc ...

  6. POJ 3278 The merchant

    传送门 Time Limit: 3000MS Memory Limit: 65536K Description There are N cities in a country, and there i ...

  7. poj 3728 The merchant(LCA)

    Description There are N cities in a country, and there is one and only one simple path between each ...

  8. ThoughtWorks Merchant's Guide To The Galaxy

    ThoughtWorks笔试题之Merchant's Guide To The Galaxy解析 一.背景 在某网站上看到ThoughtWorks在武汉招人,待遇在本地还算不错,就投递了简历.第二天H ...

  9. [POJ 3728]The merchant

    Description There are N cities in a country, and there is one and only one simple path between each ...

随机推荐

  1. Coursera在线学习---第九节(1).异常数据检测(Anomaly Detection)

    一.如何构建Anomaly Detection模型? 二.如何评估Anomaly Detection系统? 1)将样本分为6:2:2比例 2)利用交叉验证集计算出F1值,可以用F1值选取概率阈值ξ,选 ...

  2. 如何才可以干掉Cortana进程,开机不启动

    直接禁用即可WIN——设置——隐私——语音.墨迹书写和键入——停止收集有关我的信息——关闭

  3. Android 开发之避免被第三方使用代理抓包

    现象:charles抓不到包,但wireshark,HttpAnalyzor可以抓到包. 关键代码: URL url = new URL(urlStr); urlConnection = (HttpU ...

  4. 【bzoj4448】SCOI2015 情报传递

    树剖,可以相当于一个染色问题,以及询问先前节点的染色个数. 把第二种操作离线掉,然后用线段树模拟即可. #include<bits/stdc++.h> #define N 800010 # ...

  5. cpu占用高 20180108

    1.top 中的mysql占用高,在mysql中开启慢查询,用tail -f  监控慢查询日志,发现是有表的索引不合理: 2.top 中的php_fpm的进程数高,修改了一下php_fpm的配置文件p ...

  6. [Jsoi2011]柠檬

    Description Flute 很喜欢柠檬.它准备了一串用树枝串起来的贝壳,打算用一种魔法把贝壳变成柠檬.贝壳一共有 N (1 ≤ N ≤ 100,000) 只,按顺序串在树枝上.为了方便,我们从 ...

  7. Solr产品化部署

    1.下载solr-6.4.1.tgz到任意目录 2.执行tar xzf solr-6.4.1.tgz solr-6.4.1/bin/install_solr_service.sh --strip-co ...

  8. eclipse out of memory

    eclipse 安装目录 修改 eclipse.ini 在eclipse根目录下打开eclipse.ini,默认内容为(这里设置的是运行当前开发工具的JVM内存分配): -vmargs-Xms40m- ...

  9. nginx+uwsgi+django+virtualenv+supervisor部署web服务器

    wsgi 全称web server gateway interface,wsgi不是服务器,也不是python模块,只是一种协议,描述web server如何和web application通信的规则 ...

  10. json转换工具——fastjson的使用

    1.maven依赖<dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson< ...