如果直接在一条直线上,那么就建线段树

考虑每一个区间维护最小值和最大值和答案,就符合了合并的条件,一个log轻松做

那么在树上只要套一个树剖就搞定了,多一个log也不是问题

注意考虑在树上的话每一条链都有可能是正着被用和反着被用,所以存两个答案

所以维护信息只需要一个merge和一个reverse

代码如下:

 #include <cstdio>
#include <iostream>
#define mid (l+r>>1)
using namespace std;
struct node
{
int ma,mi,ans,rev_ans;
node()
{
ma=;mi=;ans=;rev_ans=;
}
node(int a,int b,int c,int d)
{
ma=a;mi=b;ans=c;rev_ans=d;
}
void rever()
{
swap(ans,rev_ans);
}
} tr[];
int N,TIME,n,m,p,q;
int to[],nex[],fir[],w[],pos[],loc[];
int fa[],size[],dep[],top[];
node merge(node a,node b)
{
return node(max(a.ma,b.ma),min(a.mi,b.mi),max(b.ma-a.mi,max(a.ans,b.ans)),max(a.ma-b.mi,max(a.rev_ans,b.rev_ans)));
}
void add(int p,int q)
{
to[++N]=q;nex[N]=fir[p];fir[p]=N;
to[++N]=p;nex[N]=fir[q];fir[q]=N;
}
int build(int now,int fat)
{
fa[now]=fat;size[now]=;dep[now]=dep[fat]+;
for(int i=fir[now];i;i=nex[i])
if(to[i]!=fat)
size[now]+=build(to[i],now);
return size[now];
}
void pou(int now,int tp)
{
top[now]=tp;loc[++TIME]=now;
pos[now]=TIME;
int best=;
for(int i=fir[now];i;i=nex[i])
if(to[i]!=fa[now])
best=best?((size[best]<size[to[i]])?to[i]:best):to[i];
if(best)
pou(best,tp);
for(int i=fir[now];i;i=nex[i])
if(to[i]!=fa[now] && to[i]!=best)
pou(to[i],to[i]);
}
void work(int now,int l,int r)
{
if(l==r)
{
tr[now]=node(w[loc[l]],w[loc[l]],,);
return;
}
work(now<<,l,mid);
work(now<<|,mid+,r);
tr[now]=merge(tr[now<<],tr[now<<|]);
}
node que(int now,int l,int r,int x,int y)
{
if(l==x && r==y)
return tr[now];
node ret=node();
if(x<=mid)
ret=que(now<<,l,mid,x,min(y,mid));
if(y>mid)
ret=merge(ret,que(now<<|,mid+,r,max(mid+,x),y));
return ret;
}
int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++)
scanf("%d",&w[i]);
for(int i=;i<n;i++)
scanf("%d%d",&p,&q),add(p,q);
build(,);
pou(,);
work(,,n);
scanf("%d",&m);
for(int i=;i<=m;i++)
{
scanf("%d%d",&p,&q);
node P=node(),Q=node();
while(top[p]!=top[q])
{
if(dep[top[p]]<dep[top[q]])
{//work on q
Q=merge(que(,,n,pos[top[q]],pos[q]),Q);
q=fa[top[q]];
}
else
{//work on p
node now=que(,,n,pos[top[p]],pos[p]);
now.rever();
P=merge(P,now);
p=fa[top[p]];
}
}
if(dep[p]<dep[q])
P=merge(P,que(,,n,pos[p],pos[q]));
else
{
node now=que(,,n,pos[q],pos[p]);
now.rever();
P=merge(P,now);
}
P=merge(P,Q);
printf("%d\n",P.ans);
}
return ;
}

poj3728The merchant树剖+线段树的更多相关文章

  1. BZOJ_2238_Mst_树剖+线段树

    BZOJ_2238_Mst_树剖+线段树 Description 给出一个N个点M条边的无向带权图,以及Q个询问,每次询问在图中删掉一条边后图的最小生成树.(各询问间独立,每次询问不对之后的询问产生影 ...

  2. BZOJ_4551_[Tjoi2016&Heoi2016]树_树剖+线段树

    BZOJ_4551_[Tjoi2016&Heoi2016]树_树剖+线段树 Description 在2016年,佳媛姐姐刚刚学习了树,非常开心.现在他想解决这样一个问题:给定一颗有根树(根为 ...

  3. BZOJ_2157_旅游_树剖+线段树

    BZOJ_2157_旅游_树剖+线段树 Description Ray 乐忠于旅游,这次他来到了T 城.T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但 ...

  4. 【BZOJ5210】最大连通子块和 树剖线段树+动态DP

    [BZOJ5210]最大连通子块和 Description 给出一棵n个点.以1为根的有根树,点有点权.要求支持如下两种操作: M x y:将点x的点权改为y: Q x:求以x为根的子树的最大连通子块 ...

  5. [LNOI2014]LCA(树剖+线段树)

    \(\%\%\% Fading\) 此题是他第一道黑题(我的第一道黑题是蒲公英) 一直不敢开,后来发现是差分一下,将询问离线,树剖+线段树维护即可 \(Code\ Below:\) #include ...

  6. [CF1007D]Ants[2-SAT+树剖+线段树优化建图]

    题意 我们用路径 \((u, v)\) 表示一棵树上从结点 \(u\) 到结点 \(v\) 的最短路径. 给定一棵由 \(n\) 个结点构成的树.你需要用 \(m\) 种不同的颜色为这棵树的树边染色, ...

  7. LOJ#3088. 「GXOI / GZOI2019」旧词(树剖+线段树)

    题面 传送门 题解 先考虑\(k=1\)的情况,我们可以离线处理,从小到大对于每一个\(i\),令\(1\)到\(i\)的路径上每个节点权值增加\(1\),然后对于所有\(x=i\)的询问查一下\(y ...

  8. BZOJ3531-[Sdoi2014]旅行(树剖+线段树动态开点)

    传送门 完了今天才知道原来线段树的动态开点和主席树是不一样的啊 我们先考虑没有宗教信仰的限制,那么就是一个很明显的树剖+线段树,路径查询最大值以及路径和 然后有了宗教信仰的限制该怎么做呢? 先考虑暴力 ...

  9. 【bzoj4699】树上的最短路(树剖+线段树优化建图)

    题意 给你一棵 $n$ 个点 $n-1$ 条边的树,每条边有一个通过时间.此外有 $m$ 个传送条件 $(x_1,y_1,x_2,y_2,c)$,表示从 $x_1$ 到 $x_2$ 的简单路径上的点可 ...

  10. POJ3237 Tree(树剖+线段树+lazy标记)

    You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edges are numbe ...

随机推荐

  1. matlab中的try...catch...end

    我们知道,matlab的代码是按行执行的,如果碰到错误行,则程序中断.try..catch可以使得可能出错代码不影响后面代码的继续执行,也可以检查,排查,解决程序的一些错误,增强代码的鲁棒性和可靠性. ...

  2. iOS 如何查看app提交审核是否使用广告标识符(IDFA)

    相信很多人被苹果拒绝过 : 您的 App 正在使用广告标识符 (IDFA).您必须先提供关于 IDFA 的使用信息或将其从 App 中移除,然后再上传您的二进制文件. 那么如何查看app里哪里用到ID ...

  3. 关于跨域获取cookie问题的解决

    需求是有2个域名:www.a.com和www.b.com,b.com需要获取a.com中的cookie,解决方法是这样的: 在a.com编写一个设置cookie的页面:set_cookie.php 代 ...

  4. Mybatis-Generator_学习_02_使用Mapper专用的MyBatis Generator插件

    源码见:https://github.com/shirayner/tk-mybatis-generator 一.要点 二.具体实现 1.项目结构 2.配置 pm.xml <?xml versio ...

  5. listen and translation exercise 52

    Two years ago my husband bought me a bicycle. Twenty of the thirty-five years I ran my own business. ...

  6. stack_2.由两个栈组成队列

    思路: 用两个栈($stack_a, $stack_b),当push的时候,压入$stack_a, 让pop的时候,先把$stack_a元素依次全部倒入$stack_b中,再对$stack_b进行po ...

  7. codeforces 706A A. Beru-taxi(水题)

    题目链接: A. Beru-taxi 题意: 问那个taxi到他的时间最短,水题; AC代码: #include <iostream> #include <cstdio> #i ...

  8. 《HTTP2基础教程》笔记

    <HTTP2基础教程>笔记 HTTP/1问题 队头阻塞 低效TCP 慢启动 拥塞避免阶段 臃肿头部 受限的优先级 高优先级无法插队 第三方资源 h2也无法很好解决 web性能优化 DNS查 ...

  9. 【Lintcode】003.Digit Counts

    题目: Count the number of k's between 0 and n. k can be 0 - 9. Example if n = 12, k = 1 in [0, 1, 2, 3 ...

  10. Codeplus2017 12月赛——可做题1

    题目:https://www.luogu.org/problemnew/show/P4030 可以发现一个矩阵是巧妙矩阵当且仅当其所有二阶子矩阵都是巧妙矩阵: 将不巧妙的二阶矩阵计为1,维护二维前缀和 ...