题意:给定一个树(10^5),m个询问(10^5),每次给定a,b,c,d,在区间[a,b]中选一个点,[c,d]选一个点,使得这两个点距离最大,输出最大距离。

题解:首先,我们有一个结论:对于一个集合的直径,如果我们将这个集合分解成两个非空集合,它的端点一定在两个非空集合的两个端这4个端点中。这非常的显然。。。

那么我们就可以做到合并两个集合,我们就可以用线段树维护每个区间的直径,就好啦,完全不用复杂的数据结构。

这道题卡时间,所以LCA要用欧拉序RMQ做。

复杂度O(nlogn)

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define N 200005
 4 inline int read(){
 5     int x=0,f=1; char a=getchar();
 6     while(a<'0' || a>'9') {if(a=='-') f=-1; a=getchar();}
 7     while(a>='0' && a<='9') x=x*10+a-'0',a=getchar();
 8     return x*f;
 9 }
10 int n,m,cnt=1,euler[2*N],dep[N],head[N],fi[N],dis[N],st[N][20],mn[N][20],Log[2*N];
11 struct edges{
12     int to,c,next;
13 }e[N];
14 struct node{
15     int x1,x2,l,r;
16 }seg[4*N];
17 struct data{
18     int x1,x2;
19 };
20 inline int getdis(int u,int v){
21     if(!u || !v) return 0;
22     u=fi[u]; v=fi[v];
23     if(u>v) swap(u,v);
24     int p,len=Log[v-u+1];
25     p=mn[u][len]<mn[v-(1<<len)+1][len]?st[u][len]:st[v-(1<<len)+1][len];
26     return dis[euler[u]]+dis[euler[v]]-2*dis[p];
27 }
28 inline void update(int x){
29     int mx=0,x1=seg[x<<1].x1,x2=seg[x<<1].x2,x3=seg[x<<1|1].x1,x4=seg[x<<1|1].x2,f;
30 if((f=getdis(x1,x2))>mx) seg[x].x1=x1,seg[x].x2=x2,mx=f; if((f=getdis(x1,x3))>mx) seg[x].x1=x1,seg[x].x2=x3,mx=f;
31 if((f=getdis(x1,x4))>mx) seg[x].x1=x1,seg[x].x2=x4,mx=f; if((f=getdis(x2,x3))>mx) seg[x].x1=x2,seg[x].x2=x3,mx=f;
32 if((f=getdis(x2,x4))>mx) seg[x].x1=x2,seg[x].x2=x4,mx=f; if((f=getdis(x3,x4))>mx) seg[x].x1=x3,seg[x].x2=x4,mx=f;
33 }
34 inline void insert(){
35     int u=read(),v=read(),c=read();
36     e[++cnt]=(edges){v,c,head[u]};head[u]=cnt;
37 }
38 void dfs(int x,int fa){
39     dep[x]=dep[fa]+1; fi[x]=euler[0]+1;
40     for(int i=head[x];i;i=e[i].next){
41         if(fa==e[i].to) continue;
42         euler[++euler[0]]=x;
43         dis[e[i].to]=dis[x]+e[i].c; dfs(e[i].to,x);
44     }
45     euler[++euler[0]]=x;
46 }
47 inline void rmq_pre(){
48     for(int i=1;i<=euler[0];i++) st[i][0]=euler[i],mn[i][0]=dep[euler[i]];
49     for(int i=1;i<=18;i++)
50         for(int j=1;j<=euler[0];j++){
51             if(j+(1<<i)-1>euler[0]) break;
52             if(mn[j][i-1]<mn[j+(1<<(i-1))][i-1]) st[j][i]=st[j][i-1],mn[j][i]=mn[j][i-1];
53             else st[j][i]=st[j+(1<<(i-1))][i-1],mn[j][i]=mn[j+(1<<(i-1))][i-1];
54         }
55     Log[0]=-1; for(int i=1;i<=euler[0];i++) Log[i]=Log[i>>1]+1;
56 }
57 void build(int l,int r,int x){
58     seg[x].l=l; seg[x].r=r;
59     if(l==r) {seg[x].x1=l; seg[x].x2=0; return;}
60     int mid=(l+r)>>1;
61     build(l,mid,x<<1);
62     build(mid+1,r,x<<1|1);
63     update(x);
64 }
65 data merge(data tmp1,data tmp2){
66     int f,mx=0,x1=tmp1.x1,x2=tmp1.x2,x3=tmp2.x1,x4=tmp2.x2;
67     data ret;
68     if((f=getdis(x1,x2))>mx) ret.x1=x1,ret.x2=x2,mx=f; if((f=getdis(x1,x3))>mx) ret.x1=x1,ret.x2=x3,mx=f;
69     if((f=getdis(x1,x4))>mx) ret.x1=x1,ret.x2=x4,mx=f; if((f=getdis(x2,x3))>mx) ret.x1=x2,ret.x2=x3,mx=f;
70     if((f=getdis(x2,x4))>mx) ret.x1=x2,ret.x2=x4,mx=f; if((f=getdis(x3,x4))>mx) ret.x1=x3,ret.x2=x4,mx=f;
71     return ret;
72 }
73 data query(int L,int R,int x){
74     int l=seg[x].l,r=seg[x].r;
75     if(l==L && r==R) {return (data){seg[x].x1,seg[x].x2};}
76     int mid=(l+r)>>1;
77     if(R<=mid) return query(L,R,x<<1);
78     else if(mid<L) return query(L,R,x<<1|1);
79     else return merge(query(L,mid,x<<1),query(mid+1,R,x<<1|1));
80 }
81 int main(){
82     n=read();
83     for(int i=1;i<n;i++) insert();
84     dfs(1,0); rmq_pre(); build(1,n,1);
85     m=read();
86     while(m--){
87         int t1,t2,a=read(),b=read(),c=read(),d=read();
88         data tmp1=query(a,b,1),tmp2=query(c,d,1);
89         t1=max(getdis(tmp1.x1,tmp2.x1),getdis(tmp1.x1,tmp2.x2));
90         t2=max(getdis(tmp1.x2,tmp2.x1),getdis(tmp1.x2,tmp2.x2));
91         printf("%d\n",max(t1,t2));
92     }
93     return 0;
94 }

转载于:https://www.cnblogs.com/enigma-aw/p/6344784.html

51nod 1766相关推荐

  1. [51nod] 1766树上的最远点对 树的直径 树剖LCA+ST表静态查询

    题意: 给你一棵带权树,q次查询,每次给出两个区间,[l1,r1][l2,r2][l_1,r_1] [l_2,r_2][l1​,r1​][l2​,r2​]从这两个区间中分别选择两个数字,使得这两个点的 ...

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

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

  3. 暑假训练-义乌(7.8-7.15)

    暑假训练 模拟赛 图表 数据 7.8(lxl) 7.9(lxl) 7.10(lxl) 7.11(lxl) 7.12(wls) 7.13(wls) 7.14(wls) 7.15(lfds) 训练 数据结 ...

  4. 2019 CCSU GOLD!!!

    线段树专场 更新结点,更新区间,区间求和(平均数)+ 树链剖分 51Nod 1199 Money out of Thin Air 更新结点,区间最值,结点查找,区间求和 51Nod 1364 最大字典 ...

  5. 51nod 1617 奇偶数组

    传送门 回来看一眼51nod,发现自己掉到rank4了,赶紧切道题回rank3. 一眼不会做,这种东西应该慢慢找规律吧--然后看到数据范围其实比较小,应该是单次log的,那是不是可以分治啊. #inc ...

  6. 51NOD 1773:A国的贸易——题解

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1773 参考1:FWT讲解 https://www.cnblogs.com ...

  7. 51nod 1040:最大公约数之和(数论)

    题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1040 给出一个n,求1-n这n个数,同n的最大公约数的和. ...

  8. (DP)51NOD 1183 编辑距离

    编辑距离,又称Levenshtein距离(也叫做Edit Distance),是指两个字串之间,由一个转成另一个所需的最少编辑操作次数.许可的编辑操作包括将一个字符替换成另一个字符,插入一个字符,删除 ...

  9. 斜率小于0的连线数量 51Nod - 1107 (树状数组+离散化)

    二维平面上N个点之间共有C(n,2)条连线.求这C(n,2)条线中斜率小于0的线的数量. 二维平面上的一个点,根据对应的X Y坐标可以表示为(X,Y).例如:(2,3) (3,4) (1,5) (4, ...

最新文章

  1. 黑客基础知识与防护(二)
  2. css3 box-sizing:border-box 实现div一行多列
  3. 反射获取空参数成员方法并运行
  4. Linux网卡eth0变成eth1修改方法
  5. 815 计算机专业基础综合,2018年华东理工大学信息科学与工程学院815计算机专业基础综合之计算机操作系统考研基础五套测试题...
  6. win10系统用户访问ftp服务器被拒绝,关于windows2003下ftp用户名无法访问FTP服务器的问题...
  7. qq五笔linux,QQ五笔 - 五笔小字典 QQ绑定很实用
  8. java简单小项目_Java简易抽奖系统小项目
  9. 第四课-Log的使用
  10. Android 应用开发(36)---LinearLayout(线性布局)
  11. tcpdf html 支持css吗,TCPDF 5.1 发布,增加对CSS的支持
  12. 斐波那契数列的Python简单实现
  13. 酒桌游戏c语言,拯救冷场,这十三款经典酒桌游戏你玩过几个?
  14. Python实现统计代码行数功能
  15. 华为手机热点无法连接_华为手机热点无法连接
  16. 好用的网络拓扑绘制软件亿图图示安装以及使用
  17. redis-trib.rb命令详解
  18. JUC种常用的辅助类
  19. oracle漏洞修补,01-oracle漏洞修复
  20. 实验记录 | 8/7 阶段性结果整理(一)

热门文章

  1. 工信部企业信息核查 谋定“互联网+监管”经信研究创新实践
  2. 云时代架构阅读笔记十五——架构设计思维(一)
  3. 第十二天Python学习记录
  4. 20145324 20145325 《信息安全系统设计基础》实验三
  5. 【皇甫】☀一本好书 你值得浏览
  6. APACHE服务器出现No input file specified.的完美解决方案
  7. 文档生成工具Sandcastle Help File Builder
  8. mysql 和 oracle 的一些区别
  9. 如何为Oracle配置多个监听器
  10. 如何系统性的分析一个新idea的可行性?