题意: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. C# PropertyInfo(官网)

    using System; using System.Reflection; class Module1 { public static void Main() { // This variable ...

  2. Codeforces Round #235 (Div. 2) D (dp)

    以为是组合,后来看着像数位dp,又不知道怎么让它不重复用..然后就没思路 了. 其实状压就可以了 状压是可以确定一个数的使用顺序的 利用01也可以确定所有的数的使用以及不重复 dp[i+1<&l ...

  3. 11.2Java-多态

    一.父类 public class Fu { public void show(){ System.out.println("父类"); } } 二.子类 public class ...

  4. SpringBoot2.1.3修改tomcat参数支持请求特殊符号

    最近遇到一个问题,比如GET请求中,key,value中带有特殊符号,请求会报错,见如下URL: http://xxx.xxx.xxx:8081/aaa?key1=val1&a.[].id=1 ...

  5. 原型模式及php实现

    原型模式: 通过复制已经存在的实例来返回新的实例,而不是新建实例,并且原型(被复制的实例)是可定制的:原型模式多用于创建复杂的或耗时的实例,这种情况下,复制一个已经存在的实例是程序运行更高效无疑是一种 ...

  6. poj3050 Hopscotch

    思路: 水题. 实现: #include <iostream> #include <cstdio> #include <set> using namespace s ...

  7. CentOS 7 下配置 firewalld(firewall-cmd)实现 NAT 转发 软路由

    如果配合 DHCP 服务或实现更多功能. ☼ NAT 转发软路由 开启 NAT 转发之后,只要本机可以上网,不论是单网卡还是多网卡,局域网内的其他机器可以将默认网关设置为已开启 NAT 转发的服务器 ...

  8. iOS---小经验分享

    1.字符串在block中得赋值 定义一个全局变量,<字符串>当这个字符串用copy修饰的时候,然后再在block中赋值,当在block块之外访问时,不能得到字符创的值.此时字符串应该设置为 ...

  9. greenplum安装札记(待完善)

    1.安装配置 1.1硬件配置 硬件服务器用到某私有云中ip段为192.168.228.111-192.168.228.120的十台服务器,相关主要配置如下表: 类别 主机名 IP 内存 硬盘 主要目录 ...

  10. ajax 请求spring之post

    # 背景 现在使用spring boot开发一个web应用是非常普遍的了,ajax请求更是标配:那么你在ajax请求时,是否遇到过在controller中获取不到参数的情况呢?特别是post请求: # ...