题意: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. iOS开发之邮件发送代码

    邮件发送功能是由MessageUI Framework提供的,这个框架是iPhone sdk中最简单的框.由一个类.一个视图控制器,一个protocol组成. 一.创建视图控制器: MFMailCom ...

  2. 移动web开发基础(一)——像素

    这篇文章要弄清楚2个问题:一.什么是逻辑像素和物理像素:二.这两者有什么关系. 对于问题一,先抛出两个概念.我们经常使用的px就是逻辑像素,是浏览器使用的抽象单位:物理像素又和dp/pt(设备无关像素 ...

  3. AJPFX关于多态的应用

    要求设计一个方法,要求此方法可以接受A类的任意子类对象,并调用方法,此时,如果不使用对象多态性,那代码肯定会类似如下 class A{                    // 定义类A publi ...

  4. VS2012出现加载失败时的解决办法 win7同样适用

    今天更新了WIN8系统补丁,然后就出现了大量的问题,特别是经常用的软件像VS2012 老是加载失败,还说是缺少什么包一类的,弄了好长段时间终于解决了,现在将经验分享下 工具/原料 VS2012+WIN ...

  5. 阿里云ecs绑定域名

    在阿里云服务器ECS一切配置ok后,通过域名一直访问不成功,结果发现还需要在后台进行安全组的规则设定:

  6. select * from a, b的意思

    其结果中总记录数为a表记录数乘以b表记录数,a的每条记录都会重复列出b记录总数次 很多晦涩的sql都要通过测试具体的数据来理解

  7. IE主页被恶意修改处理办法

    HKEY_USERS/.DEFAULT/Software/Policies/Microsoft/Internet Explorer/Control Panel 下的DWORD值“homepage”的键 ...

  8. android 开源

    http://blog.csdn.net/xiaoxiao_job/article/details/45196119?ref=myread MPAndroidChart https://github. ...

  9. Android(java)学习笔记190:ContentProvider使用之学习ContentProvider(内容提供者)的目的

    1. 使用ContentProvider,把应用程序私有的数据暴露给别的应用程序,让别的应用程序完成对自己私有的数据库数据的增删改查的操作. 2. ContentProvider的应用场景: 获取手机 ...

  10. C#中练级orcle数据查询

    直接贴代码哈哈哈, public DataTable getInfo(int flag) { OracleConnection conn = null; DataSet ds = new DataSe ...