【51NOD1766】树上的最远点对(线段树,LCA,RMQ)
题意: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)的更多相关文章
- 51 nod 1766 树上的最远点对(线段树+lca)
1766 树上的最远点对 基准时间限制:3 秒 空间限制:524288 KB 分值: 80 难度:5级算法题 n个点被n-1条边连接成了一颗树,给出a~b和c~d两个区间,表示点的标号请你求出两个 ...
- csu 1798(树上最远点对,线段树+lca)
1798: 小Z的城市 Time Limit: 5 Sec Memory Limit: 128 MBSubmit: 60 Solved: 16[Submit][Status][Web Board] ...
- 51Nod1766 树上的最远点对 ST表 LCA 线段树
原文链接https://www.cnblogs.com/zhouzhendong/p/51Nod1766.html 题目传送门 - 51Nod1766 题意 n个点被n-1条边连接成了一颗树,给出a~ ...
- 51nod 1766 树上的最远点对——线段树
n个点被n-1条边连接成了一颗树,给出a~b和c~d两个区间,表示点的标号请你求出两个区间内各选一点之间的最大距离,即你需要求出max{dis(i,j) |a<=i<=b,c<=j& ...
- 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 ...
- 线段树+RMQ问题第二弹
线段树+RMQ问题第二弹 上篇文章讲到了基于Sparse Table 解决 RMQ 问题,不知道大家还有没有印象,今天我们会从线段树的方法对 RMQ 问题再一次讨论. 正式介绍今天解决 RMQ 问题的 ...
- POJ 3368 Frequent values 线段树与RMQ解法
题意:给出n个数的非递减序列,进行q次查询.每次查询给出两个数a,b,求出第a个数到第b个数之间数字的最大频数. 如序列:-1 -1 1 1 1 1 2 2 3 第2个数到第5个数之间出现次数最多的是 ...
- POJ-3264 Balanced Lineup(区间最值,线段树,RMQ)
http://poj.org/problem?id=3264 Time Limit: 5000MS Memory Limit: 65536K Description For the daily ...
- 【做题】51Nod1766树上的最远点对——直径&线段树
原文链接 https://www.cnblogs.com/cly-none/p/9890837.html 题意:给出一棵大小为\(n\)的树,边有边权.\(m\)次询问,每次给出两个标号区间\([a, ...
- 51Nod1766 树上的最远点对
1766 树上的最远点对 n个点被n-1条边连接成了一颗树,给出a~b和c~d两个区间,表示点的标号请你求出两个区间内各选一点之间的最大距离,即你需要求出max{dis(i,j) |a<=i&l ...
随机推荐
- iOS判断输入的字符串是否是纯数字
主要用于判断输入到TextField的内容是不是数字,比如需要输入电话号码的时候. 网上查看了一些资料,一般都是通过协议. 以下内容来自:http://www.2cto.com/kf/201404/2 ...
- web api 解决Ajax请求跨域问题
前端ajax请求接口时,经常出现跨域问题,当然了解决方法有很多种,比如: http://www.jb51.net/article/68424.htm 我本人恰好前后端都会一点,所以直接在接口端处理. ...
- 工作记录 SQL prompt .net平台版本安装
昨天泡脚了,虽然依然睡的很晚,但是身体很舒服,尽量坚持把 上午尝试用一根网线,链接服务器和笔记本,但是设置好了,Ping不通. 下午安装SQL插件SQL prompt https://www.cnbl ...
- reveal.js让程序员做ppt也享受快乐
前言 程序员除了会写的一手漂亮的代码,也要求做出风格优雅的PPT,诸如向领导汇报工作.向小组成员反馈项目进展自己的工作等等.就本人而言,做ppt还要去找模板,还需要设计风格,内心是焦灼的.于是乎,我搜 ...
- js 和 java 将时间倒计时显示
需求:用户购买产品,创建了一个订单,但是还么有支付,此时给用户三十分钟剩余支付时间,前台页面做倒计时功能,时间到达时,更改订单状态 ,输出的格式是:29:23 java 实现 package com. ...
- win7+idea+maven搭建spark源码阅读环境
1.参考. 利用IDEA工具编译Spark源码(1.60~2.20) https://blog.csdn.net/He11o_Liu/article/details/78739699 Maven编译打 ...
- Android Studio 打包APK时,出现3个或多个APK
Android Studio 打包APK时,原来只会出现一个apk,结果现在出现3个apk,仔细检查了一下项目文件发现: Android Studio 的 buid.gradle文件里有个配置项被更改 ...
- Win7 32位 遇到微软 silverlight 5.0安装失败的解决办法
刚开始,也是尝试下载安装,多次都是到99%,提示安装失败! 也查找了很多网上朋友分享的办法,还是不行.重新建立一个管理员账号,还是不行. 后来反复不断的测试,找到原因了,安装99%不成功,但是卸载程序 ...
- Android网站
http://blog.csdn.net/airsaid/article/details/52902299 android调用传感器的代码 http://blog.csdn.net/huangbiao ...
- java was started but returned exit code =-805306369的处理方法
Myeclipse出现java was started but returned exit code =-805306369的错误,如图: 解决方法: 换个workspaces:换个工作目录,估计估计 ...