像树的直径一样,两个集合的最长路也是由两个集合内部的最长路的两个端点组成的,于是我们知道了两个集合的最长路,枚举一下两两端点算出答案就可以合并了,所以就可以用线段树维护一个区间里的最长路了。

#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<cmath>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn=,inf=1e9;
struct tjm{int too,dis,pre;}e[maxn];
struct poi{int p[];ll dis;}tree[maxn<<];
int n,m,a,b,x,y,z,tot;
int d[maxn],son[maxn],size[maxn],fa[maxn],top[maxn],last[maxn];
ll dep[maxn];
inline void read(int &k)
{
int f=;k=;char c=getchar();
while(c<''||c>'')c=='-'&&(f=-),c=getchar();
while(c<=''&&c>='')k=k*+c-'',c=getchar();
k*=f;
}
void add(int x,int y,int z){e[++tot].too=y;e[tot].dis=z;e[tot].pre=last[x];last[x]=tot;}
void dfs1(int x)
{
size[x]=;d[x]=d[fa[x]]+;
for(int i=last[x],too=e[i].too;i;i=e[i].pre,too=e[i].too)
if(too!=fa[x])
{
dep[too]=dep[x]+e[i].dis;
fa[too]=x;dfs1(too);
size[x]+=size[too];
if(size[too]>size[son[x]])son[x]=too;
}
}
void dfs2(int x,int tp)
{
top[x]=tp;
if(son[x])dfs2(son[x],tp);
for(int i=last[x],too=e[i].too;i;i=e[i].pre,too=e[i].too)
if(too!=fa[x]&&too!=son[x])dfs2(too,too);
}
int lca(int x,int y)
{
int f1=top[x],f2=top[y];
while(f1!=f2)
{
if(d[f1]<d[f2])swap(x,y),swap(f1,f2);
x=fa[f1];f1=top[x];
}
if(d[x]<d[y])swap(x,y);
return y;
}
void pushup(poi x,poi y,ll &dist,int &p1,int &p2)
{
if(x.dis>y.dis)dist=x.dis,p1=x.p[],p2=x.p[];
else dist=y.dis,p1=y.p[],p2=y.p[];
for(int i=;i<=;i++)
for(int j=;j<=;j++)
if(x.p[i]&&y.p[j])
{
ll dis=dep[x.p[i]]+dep[y.p[j]]-(dep[lca(x.p[i],y.p[j])]<<);
if(dis>dist)dist=dis,p1=x.p[i],p2=y.p[j];
}
}
void build(int x,int l,int r)
{
if(l==r){tree[x].p[]=tree[x].p[]=l;return;}
int mid=(l+r)>>;
build(x<<,l,mid);build(x<<|,mid+,r);
pushup(tree[x<<],tree[x<<|],tree[x].dis,tree[x].p[],tree[x].p[]);
}
void query(int x,int l,int r,int cl,int cr,ll &dis,int &p1,int &p2)
{
if(cl<=l&&r<=cr){dis=tree[x].dis;p1=tree[x].p[];p2=tree[x].p[];return;}
int mid=(l+r)>>;
poi t1,t2;t1.dis=t2.dis=-;t1.p[]=t1.p[]=t2.p[]=t2.p[]=;
if(cl<=mid)query(x<<,l,mid,cl,cr,t1.dis,t1.p[],t1.p[]);
if(cr>mid)query(x<<|,mid+,r,cl,cr,t2.dis,t2.p[],t2.p[]);
pushup(t1,t2,dis,p1,p2);
}
int main()
{
read(n);
for(int i=;i<n;i++)read(x),read(y),read(z),add(x,y,z),add(y,x,z);
dfs1();dfs2(,);
build(,,n);
read(m);
for(int i=;i<=m;i++)
{
read(a),read(b),read(x),read(y);
poi t1,t2;t1.dis=t2.dis=t1.p[]=t1.p[]=t2.p[]=t2.p[]=;ll dis;int p1,p2;
query(,,n,a,b,dis,t1.p[],t1.p[]);query(,,n,x,y,dis,t2.p[],t2.p[]);
pushup(t1,t2,dis,p1,p2);
printf("%lld\n",dis);
}
}

51nod 1766 树上的最远点对(线段树)的更多相关文章

  1. 51nod 1766 树上的最远点对——线段树

    n个点被n-1条边连接成了一颗树,给出a~b和c~d两个区间,表示点的标号请你求出两个区间内各选一点之间的最大距离,即你需要求出max{dis(i,j) |a<=i<=b,c<=j& ...

  2. 51 nod 1766 树上的最远点对(线段树+lca)

    1766 树上的最远点对 基准时间限制:3 秒 空间限制:524288 KB 分值: 80 难度:5级算法题   n个点被n-1条边连接成了一颗树,给出a~b和c~d两个区间,表示点的标号请你求出两个 ...

  3. 51nod 1766 树上的最远点对 | LCA ST表 线段树 树的直径

    51nod 1766 树上的最远点对 | LCA ST表 线段树 树的直径 题面 n个点被n-1条边连接成了一颗树,给出a~b和c~d两个区间,表示点的标号请你求出两个区间内各选一点之间的最大距离,即 ...

  4. [51nod 1766]树上的最远点对 (树的直径+ST表求lca+线段树)

    [51nod 1766]树上的最远点对 (树的直径+ST表求lca+线段树) 题面 给出一棵N个点的树,Q次询问一点编号在区间[l1,r1]内,另一点编号在区间[l2,r2]内的所有点对距离最大值.\ ...

  5. 51Nod 1766 树上的最远点对

    Description 一棵树,询问两个端点编号分别在在 \([a,b]\) 和 \([c,d]\) 两个区间中的最长链. Sol 线段树+ST表. 树上最长链可以合并,只需要合并两个区间最长链的两个 ...

  6. 【树形结构】51nod 1766 树上的最远点对

    题目内容 \(n\)个点被\(n−1\)条边连接成了一颗树,边有权值\(w_i\).有\(q\)个询问,给出\([a,b]\)和\([c,d]\)两个区间,表示点的标号请你求出两个区间内各选一点之间的 ...

  7. 【51nod】1766 树上的最远点对

    [题意]给定n个点的树,m次求[a,b]和[c,d]中各选出一个点的最大距离.abcd是标号区间,n,m<=10^5 [算法]LCA+树的直径理论+线段树 [题解] 树的直径性质:距离树上任意点 ...

  8. 51Nod.1766.树上最远点对(树的直径 RMQ 线段树/ST表)

    题目链接 \(Description\) 给定一棵树.每次询问给定\(a\sim b,c\sim d\)两个下标区间,从这两个区间中各取一个点,使得这两个点距离最远.输出最远距离. \(n,q\leq ...

  9. csu 1798(树上最远点对,线段树+lca)

    1798: 小Z的城市 Time Limit: 5 Sec  Memory Limit: 128 MBSubmit: 60  Solved: 16[Submit][Status][Web Board] ...

随机推荐

  1. 进阶篇:4.1)DFA设计指南:简化产品设计(kiss原则)

    本章目的:理解kiss原则,明确如何简化产品的设计. 1.前言:kiss原则,优化产品的第一原则 如果要作者选出一个优化产品的最好方法,那一定是kiss原则莫属.从产品的整体设计到公差的分析,kiss ...

  2. ArrayList 源码分析 -- 扩容问题及序列化问题

    目录 一.前言二.ArrayList 的继承与实现关系    2.1 ArrayList.java    2.2 抽象类AbstractList.java    2.3 接口List.java     ...

  3. Redis5.0:在这些场景使用,高效率还低成本!

    很多大型电商网站.视频直播和游戏应用等,存在大规模数据访问,对数据查询效率要求高,且数据结构简单,不涉及太多关联查询. 这种场景使用Redis,在速度上对传统磁盘数据库有很大优势,能够有效减少数据库磁 ...

  4. LVM缩小根分区

    逻辑卷不是根分区都可以在线扩容和缩小 根分区是可以在线扩容,但不可以在线缩小 Linux系统进入救援模式 依次选择: 欢迎界面 ---------- Rescue installed system C ...

  5. 杂谈微服务架构下SSO&OpenAPI访问的方案。

    本篇杂谈下微服务架构下WEB应用的浏览器与OpenAPI访问架构与方案.读者可对比传统架构下应用的此话话题的区别.或者有其它方案的欢迎交流

  6. Fast R-CNN学习总结

    Fast R-CNN是R-CNN的改良版,同时也吸取了SPP-net中的方法.在此做一下总结. 论文中讲到在训练阶段,训练一个深度目标检测网络(VGG16),训练速度要比R-CNN快9倍左右,比SPP ...

  7. 微软职位内部推荐-Principal Development Lead - SharePoint

    微软近期Open的职位: SharePoint is a multi-billion dollar enterprise business that has grown from an on-prem ...

  8. java 乐观锁 vs 悲观锁

    在数据库的锁机制中介绍过,数据库管理系统(DBMS)中的并发控制的任务是确保在多个事务同时存取数据库中同一数据时不破坏事务的隔离性和统一性以及数据库的统一性. 悲观锁其实就是 完全同步 比如 sync ...

  9. 《IT小小鸟》的阅读心得

    新年过后我们迎来大一下学期,想想刚迈入大学的我们,充满着好奇与兴奋,仿佛就在昨天.时光飞逝而今,虽经过一学期的学习,仍对计算机专业充满困惑,对未来充满迷茫. 在我感到迷茫的时候,老师给我们介绍了这样的 ...

  10. 找"数学口袋精灵"bug

    团队成员的博客园地址: 刘森松:http://home.cnblogs.com/u/lssh/ 郭志豪:http://home.cnblogs.com/u/gzh13692021053/ 谭宇森:ht ...