$n \leq 500000$的树给$m \leq 500000$个路径,$q \leq 500000$个询问每次问一个区间的路径交。

路径交口诀:(前方高能)

判有交,此链有彼祖;

取其交,最深两两祖。

说成人话就是:判两条路径有没有交,只要一条链的lca在另一条链上就一定有交;取两条路径的交,把两条路径的端点两两求出四对lca,最深那两个就是路径交。

证明?我会还用口诀!

由于需要很多很多次查lca,这里用欧拉序+st表求。查区间路径交可以线段树也可以st表,毕竟重复的部分算两次没问题。

  1. //#include<iostream>
  2. #include<cstring>
  3. #include<cstdlib>
  4. #include<cstdio>
  5. //#include<time.h>
  6. //#include<complex>
  7. #include<algorithm>
  8. #include<stdlib.h>
  9. using namespace std;
  10.  
  11. int n,m,q;
  12. #define maxn 500011
  13. struct Edge{int to,next,v;}edge[maxn<<]; int first[maxn],le=;
  14. void in(int x,int y,int v) {Edge &e=edge[le]; e.to=y; e.v=v; e.next=first[x]; first[x]=le++;}
  15. void insert(int x,int y,int v) {in(x,y,v); in(y,x,v);}
  16.  
  17. int len,dep[maxn],id[maxn],st[maxn<<][],Log[maxn<<];
  18. #define LL long long
  19. LL dis[maxn];
  20. void dfs(int x,int fa)
  21. {
  22. st[++len][]=x; id[x]=len; dep[x]=dep[fa]+;
  23. for (int i=first[x];i;i=edge[i].next)
  24. {
  25. Edge &e=edge[i]; if (e.to==fa) continue;
  26. dis[e.to]=dis[x]+e.v; dfs(e.to,x); st[++len][]=x;
  27. }
  28. }
  29.  
  30. void makest()
  31. {
  32. Log[]=-; for (int i=;i<=len;i++) Log[i]=Log[i>>]+;
  33. for (int j=;j<=;j++)
  34. for (int i=,to=len-(<<j)+;i<=to;i++)
  35. st[i][j]=dep[st[i][j-]]<dep[st[i+(<<(j-))][j-]]?st[i][j-]:st[i+(<<(j-))][j-];
  36. }
  37.  
  38. int lca(int x,int y)
  39. {
  40. if (id[x]>id[y]) {int t=x;x=y;y=t;} x=id[x]; y=id[y];
  41. int l=Log[y-x+];
  42. return dep[st[x][l]]<dep[st[y-(<<l)+][l]]?st[x][l]:st[y-(<<l)+][l];
  43. }
  44.  
  45. struct Line{int x,y;}line[maxn];
  46. bool cmpdep(const int a,const int b) {return dep[a]<dep[b];}
  47. Line combine(Line a,Line b)
  48. {
  49. if (a.x==- || b.x==-) return (Line){-,-};
  50. int l1=lca(a.x,a.y),l2=lca(b.x,b.y);
  51. int t1=lca(l1,b.x),t2=lca(l1,b.y),t3=lca(a.x,l2),t4=lca(a.y,l2);
  52. bool flag=;
  53. if ((t1==l1 && dep[t1]>=dep[l2]) || (t2==l1 && dep[t2]>=dep[l2])) flag=;
  54. if ((t3==l2 && dep[t3]>=dep[l1]) || (t4==l2 && dep[t4]>=dep[l1])) flag=;
  55. if (!flag) return (Line){-,-};
  56. int d[]; d[]=lca(a.x,b.x); d[]=lca(a.x,b.y); d[]=lca(a.y,b.x); d[]=lca(a.y,b.y);
  57. sort(d,d+,cmpdep); return (Line){d[],d[]};
  58. }
  59.  
  60. struct SMT
  61. {
  62. struct Node
  63. {
  64. int ls,rs;
  65. Line com;
  66. }a[maxn<<];
  67. int size,n;
  68. void clear(int m) {size=; n=m;}
  69. void up(int x)
  70. {
  71. int &p=a[x].ls,&q=a[x].rs;
  72. a[x].com=combine(a[p].com,a[q].com);
  73. }
  74. void build(int &x,int L,int R)
  75. {
  76. x=++size;
  77. if (L==R) {a[x].com=line[L]; a[x].ls=a[x].rs=; return;}
  78. int mid=(L+R)>>;
  79. build(a[x].ls,L,mid); build(a[x].rs,mid+,R); up(x);
  80. }
  81. void build() {int x; build(x,,n);}
  82. int ql,qr;
  83. Line Query(int x,int L,int R)
  84. {
  85. if (ql<=L && R<=qr) return a[x].com;
  86. int mid=(L+R)>>; Line ans; bool flag=;
  87. if (ql<=mid) ans=Query(a[x].ls,L,mid),flag=;
  88. if (qr>mid) {if (flag) ans=combine(Query(a[x].rs,mid+,R),ans); else ans=Query(a[x].rs,mid+,R);}
  89. return ans;
  90. }
  91. Line query(int L,int R) {ql=L; qr=R; return Query(,,n);}
  92. }t;
  93.  
  94. int main()
  95. {
  96. scanf("%d",&n);
  97. for (int i=,x,y,v;i<n;i++) scanf("%d%d%d",&x,&y,&v),insert(x,y,v);
  98. len=; dfs(,); makest();
  99. scanf("%d",&m);
  100. for (int i=;i<=m;i++) scanf("%d%d",&line[i].x,&line[i].y);
  101. t.clear(m); t.build();
  102. scanf("%d",&q);
  103. while (q--)
  104. {
  105. int x,y; scanf("%d%d",&x,&y);
  106. Line ans=t.query(x,y);
  107. printf("%lld\n",dis[ans.x]+dis[ans.y]-*dis[lca(ans.x,ans.y)]);
  108. }
  109. return ;
  110. }

hdu6110:路径交的更多相关文章

  1. hihocoder[Offer收割]编程练习赛19 D 相交的铁路线(树上路径交)

    傻逼题... 裸的树上路径交 两条树上的路径$[a,b]$和$[c,d]$有交,则有$lca(a,b)$在$[c,d]$上或$lca(c,d)$在$[a,b]$上. 其实只要深度大的$lca$在另一条 ...

  2. hdu 6010 路径交

    hdu 6010 路径交(lca + 线段树) 题意: 给出一棵大小为\(n\)的树和\(m\)条路径,求第\(L\)条路径到第\(R\)条路径的交的路径的长度 思路: 本题的关键就是求路径交 假设存 ...

  3. 【百度之星初赛A】路径交 LCA+线段树

    [百度之星初赛A]路径交 Problem Description 给定一棵n个点的树,以及m条路径,每次询问第L条到第R条路径的交集部分的长度(如果一条边同时出现在2条路径上,那么它属于路径的交集). ...

  4. 2017"百度之星"程序设计大赛 - 初赛(A) [ hdu 6108 小C的倍数问题 ] [ hdu 6109 数据分割 ] [ hdu 6110 路径交 ] [ hdu 6112 今夕何夕 ] [ hdu 6113 度度熊的01世界 ]

    这套题体验极差. PROBLEM 1001 - 小C的倍数问题 题 OvO http://acm.hdu.edu.cn/showproblem.php?pid=6108 (2017"百度之星 ...

  5. 【HDU】6110 路径交(2017百度之星) 线段树+RMQ-LCA+树链的交

    [题目]2017"百度之星"程序设计大赛 - 初赛(A) [题意]给定n个点的带边权树,m条编号1~m的路径,Q次询问编号区间[L,R]所有链的交集的长度.n<=500000 ...

  6. [51nod 1830] 路径交

    问题描述 给定一棵n个点的树,以及m条路径,每次询问第L条到第R条路径的交集部分的长度(如果一条边同时出现在2条路径上,那么它属于路径的交集). 输入格式 第一行一个数n(n<=500,000) ...

  7. BZOJ1906树上的蚂蚁&BZOJ3700发展城市——RMQ求LCA+树链的交

    题目描述 众所周知,Hzwer学长是一名高富帅,他打算投入巨资发展一些小城市. Hzwer打算在城市中开N个宾馆,由于Hzwer非常壕,所以宾馆必须建在空中,但是这样就必须建立宾馆之间的连接通道.机智 ...

  8. hdu6110(线段树+lca)

    题目 http://acm.hdu.edu.cn/showproblem.php?pid=6110 分析 注意到,若干条路径的交一定也是条路径 我们可以维护一个线段树,seg[l..r]存着第l条~第 ...

  9. UOJ #150 【NOIP2015】 运输计划

    题目描述 公元 \(2044\) 年,人类进入了宇宙纪元. \(L\) 国有 \(n\) 个星球,还有 \(n-1\) 条双向航道,每条航道建立在两个星球之间,这 \(n-1\) 条航道连通了 \(L ...

随机推荐

  1. 【转】几种Java序列化方式的实现

    0.前言 本文主要对几种常见Java序列化方式进行实现.包括Java原生以流的方法进行的序列化.Json序列化.FastJson序列化.Protobuff序列化. 1.Java原生序列化 Java原生 ...

  2. pre-network android 网络优化预加载框架

    网络优化是所有app开发中非常重要的一部分,如果将网络请求前置就是在点击跳转activity之前开始网络加载那么速度将会有质的提升.也就是网络预先加载框框架. 网络预加载框架,监听式网络前置加载框架- ...

  3. 记 thoughtworks 的一次面试

    2015年的1月30号,星期五.我将要去thoughtworks面试. 最早听说thoughtworks是在学校听同学说起的.一句不经意间的引导可能会改变我的整个人生. 实话说,我之前对thought ...

  4. CAD交互绘制多段线(网页版)

    多段线又被称为多义线,表示一起画的都是连在一起的一个复合对象,可以是直线也可以是圆弧并且它们还可以加不同的宽度. 主要用到函数说明: _DMxDrawX::DrawLine 绘制一个直线.详细说明如下 ...

  5. 把txt格式数据制作成xml数据

    txt格式数据: 代码: s1=""" <object> <name>{0}</name> <pose>Unspecifi ...

  6. 利用CWinThread实现跨线程父子MFC窗口

    利用CWinThread实现跨线程父子MFC窗口 MFC对象只能由创建该对象的线程访问,而不能由其他线程访问. 不遵守该准则将导致断言(assertion)或者无法预知的程序行为等运行期错误. 在多线 ...

  7. ios之coretext

    API接口文档. https://developer.apple.com/library/mac/#documentation/Carbon/Reference/CoreText_Framework_ ...

  8. 【2018 CCPC网络赛】1004 - 费马大定理&数学

    题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=6441 Knowledge Point: 1. 费马大定理:当整数n >2时,关于x, y, z的 ...

  9. css 浮动规则

    1. 如果浮动元素的高度大于父级元素,那么浮动元素块会超过父级元素的底部.解决办法:将父级元素也设置为浮动定位. 2. 不改变box尺寸的情况下增加box内部的内边距:box-sizing: bord ...

  10. 洛谷p1049 01背包

    dp水之旅背包 题目描述 有一个箱子容量为V(正整数,0<=V<=20000),同时有n个物品(0<n<=30,每个物品有一个体积(正整数). 要求n个物品中,任取若干个装入箱 ...