题意:n个点被n-1条边连接成了一颗树,给出a~b和c~d两个区间,

表示点的标号请你求出两个区间内各选一点之间的最大距离,即你需要求出max{dis(i,j) |a<=i<=b,c<=j<=d}

n<=100000 len[i]<=100000

思路:两年前张老师出的模拟赛里的题

设区间[a,b]中最大距离点对为[x1,y1]

[c,d]为[x2,y2]

则两区间各取一个点的最值只有两两组合4种可能

而线段树中pushup有6种,可以在同一个区间中取两点

求LCA需要LCA转RMQ O(1)做 倍增或剖的话都会T

然并卵 P的常数太大了 早日转C保平安

 type arr=record
a,b:longint;
end;
var f,g:array[..,..]of longint;
t:array[..]of arr;
a,b,st,dep,dis,head,vet,next,len:array[..]of longint;
n,m,i,tot,x,y,z,ans,time,que,j,x1,y1,x2,y2,tmp,tx,ty:longint;
p,q:arr; procedure add(a,b,c:longint);
begin
inc(tot);
next[tot]:=head[a];
vet[tot]:=b;
len[tot]:=c;
head[a]:=tot;
end; function max(x,y:longint):longint;
begin
if x>y then exit(x);
exit(y);
end; procedure dfs(u,fa:longint);
var e,v:longint;
begin
inc(time); st[u]:=time; a[time]:=dep[u]; b[time]:=u;
e:=head[u];
while e<> do
begin
v:=vet[e];
if v<>fa then
begin
dep[v]:=dep[u]+;
dis[v]:=dis[u]+len[e];
dfs(v,u);
inc(time); a[time]:=dep[u]; b[time]:=u;
end;
e:=next[e];
end;
end; function min(x,y:longint):longint;
begin
if x<y then exit(x);
exit(y);
end; function lca(x,y:longint):longint;
var len,l,x1,y1:longint;
begin
x1:=st[x]; y1:=st[y];
if x1>y1 then begin x1:=st[y]; y1:=st[x]; end;
len:=y1-x1+;
l:=trunc(ln(len)/ln());
if f[x1,l]<f[y1-(<<l)+,l] then exit(g[x1,l])
else exit(g[y1-(<<l)+,l]);
end; function clac(x,y:longint):longint;
var q:longint;
begin
q:=lca(x,y);
exit(dis[x]+dis[y]-*dis[q]);
end; function pushup(x,y:arr):arr;
var t:arr;
begin
t:=x;
if clac(y.a,y.b)>clac(t.a,t.b) then t:=y;
if clac(x.a,y.a)>clac(t.a,t.b) then
begin
t.a:=x.a; t.b:=y.a;
end;
if clac(x.a,y.b)>clac(t.a,t.b) then
begin
t.a:=x.a; t.b:=y.b;
end;
if clac(x.b,y.a)>clac(t.a,t.b) then
begin
t.a:=x.b; t.b:=y.a;
end;
if clac(x.b,y.b)>clac(t.a,t.b) then
begin
t.a:=x.b; t.b:=y.b;
end;
exit(t);
end; procedure build(l,r,p:longint);
var mid:longint;
begin
if l=r then
begin
t[p].a:=l; t[p].b:=l;
exit;
end;
mid:=(l+r)>>;
build(l,mid,p<<);
build(mid+,r,p<<+);
t[p]:=pushup(t[p<<],t[p<<+]);
end; function query(l,r,x,y,p:longint):arr;
var mid:longint;
begin
if (l>=x)and(r<=y) then exit(t[p]);
mid:=(l+r)>>;
query.a:=x; query.b:=x;
if x<=mid then query:=pushup(query,query(l,mid,x,y,p<<));
if y>mid then query:=pushup(query,query(mid+,r,x,y,p<<+));
end; begin
assign(input,'51nod1766.in'); reset(input);
assign(output,'51nod1766.out'); rewrite(output);
readln(n);
for i:= to n- do
begin
readln(x,y,z);
add(x,y,z);
add(y,x,z);
end;
dfs(,);
for i:= to time do
begin
f[i,]:=a[i]; g[i,]:=b[i];
end;
m:=trunc(ln(time)/ln());
for i:= to m do
for j:= to time-(<<i)+ do
if f[j,i-]<f[j+(<<(i-)),i-] then
begin
f[j,i]:=f[j,i-]; g[j,i]:=g[j,i-];
end
else
begin
f[j,i]:=f[j+(<<(i-)),i-];
g[j,i]:=g[j+(<<(i-)),i-];
end;
build(,n,);
readln(que);
for i:= to que do
begin
readln(x1,y1,x2,y2);
p:=query(,n,x1,y1,);
q:=query(,n,x2,y2,);
ans:=;
ans:=max(ans,clac(p.a,q.a));
ans:=max(ans,clac(p.a,q.b));
ans:=max(ans,clac(p.b,q.a));
ans:=max(ans,clac(p.b,q.b));
writeln(ans);
end;
close(input);
close(output);
end.

【51NOD1766】树上的最远点对(线段树,LCA,RMQ)的更多相关文章

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

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

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

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

  3. 51Nod1766 树上的最远点对 ST表 LCA 线段树

    原文链接https://www.cnblogs.com/zhouzhendong/p/51Nod1766.html 题目传送门 - 51Nod1766 题意 n个点被n-1条边连接成了一颗树,给出a~ ...

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

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

  5. BZOJ 2588: Spoj 10628. Count on a tree-可持久化线段树+LCA(点权)(树上的操作) 无语(为什么我的LCA的板子不对)

    2588: Spoj 10628. Count on a tree Time Limit: 12 Sec  Memory Limit: 128 MBSubmit: 9280  Solved: 2421 ...

  6. 线段树+RMQ问题第二弹

    线段树+RMQ问题第二弹 上篇文章讲到了基于Sparse Table 解决 RMQ 问题,不知道大家还有没有印象,今天我们会从线段树的方法对 RMQ 问题再一次讨论. 正式介绍今天解决 RMQ 问题的 ...

  7. POJ 3368 Frequent values 线段树与RMQ解法

    题意:给出n个数的非递减序列,进行q次查询.每次查询给出两个数a,b,求出第a个数到第b个数之间数字的最大频数. 如序列:-1 -1 1 1 1 1 2 2 3 第2个数到第5个数之间出现次数最多的是 ...

  8. POJ-3264 Balanced Lineup(区间最值,线段树,RMQ)

    http://poj.org/problem?id=3264 Time Limit: 5000MS     Memory Limit: 65536K Description For the daily ...

  9. 【做题】51Nod1766树上的最远点对——直径&线段树

    原文链接 https://www.cnblogs.com/cly-none/p/9890837.html 题意:给出一棵大小为\(n\)的树,边有边权.\(m\)次询问,每次给出两个标号区间\([a, ...

  10. 51Nod1766 树上的最远点对

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

随机推荐

  1. 200 Number of Islands 岛屿的个数

    给定 '1'(陆地)和 '0'(水)的二维网格图,计算岛屿的数量.一个岛被水包围,并且通过水平或垂直连接相邻的陆地而形成.你可以假设网格的四个边均被水包围.示例 1:11110110101100000 ...

  2. Java数组的交集、并集

    // 求两个数组的交集 public static int[] SameOfTwoArrays(int[] arr1, int[] arr2) { // 新建一个空数组,用于存储交集,空数组长度应该为 ...

  3. Node.js——环境变量

  4. JS对json中某字段进行排序

    var data =[ { "cid":1, "name":"aaa", "price":1000 },{ " ...

  5. Oracle11g 审计介绍

    审计是记录数据库上方方面面操作.事件等信息,是数据安全管理的重要手段. 开启审计,虽然不同级别的审计会有不同,但是对数据库的性能是有影响的,并且占用存储空间. --1.创建审计数据专用表空间 crea ...

  6. python 需求分析

    第三章: 需求分析需求分析任务: ??? 功能分析性能分析EG: 相应时间.主存容量.磁盘容量.安全性.等可靠性和可用性出错处理需求系统发现错误时采取的行动,主要在系统关键部分设置接口需求用户接口.硬 ...

  7. 手机,平板当中浏览和编辑DWG的CAD控件出来啦!支持ARX二次开发

    控件2014.06.30 安卓开发最新更新 发布时间:2014-06-30 22:22:42 开发包下载地址:http://www.mxdraw.com/MxDraw6.0Android(201406 ...

  8. mac 目录颜色设置

    1 export CLICOLOR=1  2 export LSCOLORS=gxfxaxdxcxegedabagacad

  9. 【计算机网络】2.6 P2P应用

    第二章第六节 P2P应用 在本节内容开始前,我们要先来对P2P架构有一个宏观的认知: P2P:(Peer to Peer 对等结构)   以对等方式进行通信,并不区分客户端和服务端,而是平等关系进行通 ...

  10. laravel-admin常见错误处理

    php artisan key:generate 新的laravle会有密钥不存在的问题,这时候我们执行这句话就可以生成秘钥了