【题目】2017"百度之星"程序设计大赛 - 初赛(A)

【题意】给定n个点的带边权树,m条编号1~m的路径,Q次询问编号区间[L,R]所有链的交集的长度。n<=500000。

【算法】线段树+RMQ-LCA+树链的交

【题解】树链的交:记一条链为(a1,b1),LCA为c1。另一条链为(a2,b2),LCA为c2。记a1a2,a1b2,b1a2,b1b2的LCA为d1,d2,d3,d4,按深度排序后得deep[d1]<=deep[d2]<=deep[d3]<=deep[d4],deep[c1]<=deep[c2]。

两条链有交集当且仅当deep[c1]<=deep[d1]&&deep[c2]<=deep[d3],此时树链(d3,d4)是两条链的交。(判断是否有交还有另一种方法:一条链的LCA在另一条链上时有交)

基于此,用线段树维护m条链的交集,回答询问。用RMQ-LCA预处理后可以降低复杂度(注意欧拉序开2倍)。

总复杂度O(n log n)。

#include<cstdio>
#include<cstring>
#include<cctype>
#include<algorithm>
#define ll long long
using namespace std;
int read(){
char c;int s=,t=;
while(!isdigit(c=getchar()))if(c=='-')t=-;
do{s=s*+c-'';}while(isdigit(c=getchar()));
return s*t;
}
const int maxn=;
int dfn[maxn*],p[maxn],first[maxn],deep[maxn],Q[maxn*][],c[],d[],tot=,num=;
ll dis[maxn];
int logs[maxn*],n,m;
struct edge{int v,w,from;}e[maxn*];
struct cyc{int x,y;}O[maxn];
struct tree{int l,r;cyc o;}t[maxn*]; void insert(int u,int v,int w){tot++;e[tot].v=v;e[tot].w=w;e[tot].from=first[u];first[u]=tot;}
void dfs(int x,int fa){
dfn[++num]=x;
if(!p[x])p[x]=num;
for(int i=first[x];i;i=e[i].from)if(e[i].v!=fa){
deep[e[i].v]=deep[x]+;
dis[e[i].v]=dis[x]+e[i].w;
dfs(e[i].v,x);
dfn[++num]=x;
}
}
void prepare(){
logs[]=-;for(int i=;i<=num;i++)logs[i]=logs[i>>]+;
for(int i=;i<=num;i++)Q[i][]=dfn[i];
for(int j=;(<<j)<=num;j++){
for(int i=;i+(<<j)-<=num;i++){
if(deep[Q[i][j-]]<deep[Q[i+(<<(j-))][j-]])Q[i][j]=Q[i][j-];
else Q[i][j]=Q[i+(<<(j-))][j-];
}
}
}
int lca(int x,int y){
if(p[x]>p[y])swap(x,y);
int k=logs[p[y]-p[x]+];
return deep[Q[p[x]][k]]<deep[Q[p[y]-(<<k)+][k]]?Q[p[x]][k]:Q[p[y]-(<<k)+][k];
}
bool cmp(int a,int b){return deep[a]<deep[b];}
cyc merge(cyc o1,cyc o2){
if(!o1.x||!o2.x)return (cyc){,};
d[]=lca(o1.x,o2.x);d[]=lca(o1.x,o2.y);d[]=lca(o1.y,o2.x);d[]=lca(o1.y,o2.y);
c[]=lca(o1.x,o1.y);c[]=lca(o2.x,o2.y);
sort(d+,d++,cmp);if(deep[c[]]>deep[c[]])swap(c[],c[]);
if(deep[c[]]<=deep[d[]]&&deep[c[]]<=deep[d[]])return (cyc){d[],d[]};else return (cyc){,};//
}
void build(int k,int l,int r){
t[k].l=l;t[k].r=r;
if(l==r){t[k].o=O[l];return;}
int mid=(l+r)>>;
build(k<<,l,mid);build(k<<|,mid+,r);
t[k].o=merge(t[k<<].o,t[k<<|].o);
}
cyc query(int k,int l,int r){
if(l<=t[k].l&&t[k].r<=r)return t[k].o;
int mid=(t[k].l+t[k].r)>>;cyc x=(cyc){-,};
if(l<=mid)x=query(k<<,l,r);
if(r>mid){if(~x.x)x=merge(x,query(k<<|,l,r));else x=query(k<<|,l,r);}
return x;
}
int main(){
n=read();
for(int i=;i<n;i++){
int u=read(),v=read(),w=read();
insert(u,v,w);insert(v,u,w);
}
dfs(,);
prepare();
m=read();
for(int i=;i<=m;i++)O[i].x=read(),O[i].y=read();
build(,,m);
int T=read();
while(T--){
int l=read(),r=read();cyc x;
x=query(,l,r);
if(!x.x)printf("0\n");else
printf("%lld\n",dis[x.x]+dis[x.y]-*dis[lca(x.x,x.y)]);
}
return ;
}

这题WA之后对拍不出错,发现是生成的数据每个点的父亲编号严格小于它,导致深度关系和编号等价。

然后我在判断c1<=d1&&c2<=d3的时候比较了编号而非深度,于是GG。

【HDU】6110 路径交(2017百度之星) 线段树+RMQ-LCA+树链的交的更多相关文章

  1. 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"百度之星 ...

  2. HDU 6109 数据分割 【并查集+set】 (2017"百度之星"程序设计大赛 - 初赛(A))

    数据分割 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  3. HDU 6108 小C的倍数问题 【数学】 (2017"百度之星"程序设计大赛 - 初赛(A))

    小C的倍数问题 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Sub ...

  4. HDU 6122 今夕何夕 【数学公式】 (2017"百度之星"程序设计大赛 - 初赛(A))

    今夕何夕 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submis ...

  5. HDU 6113 度度熊的01世界 【DFS】(2017"百度之星"程序设计大赛 - 初赛(A))

    度度熊的01世界 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  6. 2017"百度之星"程序设计大赛 - 复赛1005&&HDU 6148 Valley Numer【数位dp】

    Valley Numer Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tota ...

  7. 2017"百度之星"程序设计大赛 - 复赛1003&&HDU 6146 Pokémon GO【数学,递推,dp】

    Pokémon GO Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total ...

  8. 2017"百度之星"程序设计大赛 - 复赛1001&&HDU 6144 Arithmetic of Bomb【java大模拟】

    Arithmetic of Bomb Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

  9. HDU 6118 度度熊的交易计划 【最小费用最大流】 (2017"百度之星"程序设计大赛 - 初赛(B))

    度度熊的交易计划 Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total S ...

随机推荐

  1. lintcode-457-经典二分查找问题

    457-经典二分查找问题 在一个排序数组中找一个数,返回该数出现的任意位置,如果不存在,返回-1 样例 给出数组 [1, 2, 2, 4, 5, 5]. 对于 target = 2, 返回 1 或者 ...

  2. C#高级编程 (第六版) 学习 第四章:继承

    第四章 继承 1,继承的类型 实现继承: 一个类派生于一个基类型,拥有该基类型所有成员字段和函数. 接口继承 一个类型只继承了函数的签名,没有继承任何实现代码.   2,实现继承 class MyDe ...

  3. mosquitto启动时Address already in use 和 一般的 Address already in use

    对于mosquitto启动时的地址占用错误,可能是mosquitto启动之后没关掉,进程一直占用了端口.查看mosquitto相关的进程,然后关掉就可启动了. 关掉mosquitto进程即可 参考: ...

  4. [Prism框架实用分享]如何在Prism应用程序中使用日志

    前言 在Prism中有关日志的命名空间: Microsoft.Practices.Prism.Logging 在Prism中,你可以使用Prism自带的Logger(比如TextLogger等),也可 ...

  5. MySQL---索引算法B+/B-树原理(一)

    B-树 1 .B-树定义 B-树是一种平衡的多路查找树,它在文件系统中很有用. 定义:一棵m 阶的B-树,或者为空树,或为满足下列特性的m 叉树: ⑴树中每个结点至多有m 棵子树: ⑵若根结点不是叶子 ...

  6. 第123天:移动web开发中的常见问题

    一.函数库 underscoreJS _.template: <ol class="carousel-indicators"> <!--渲染的HTML字符串--& ...

  7. Socket 传一幅图片给另一个终端

    练习Socket传文件,先添加一个组件,简化socket发送和接收文件, 获取IP和端口的类 public static class AddressHelper { /// <summary&g ...

  8. java map添加另一个map时候 键值对的类型要一致

    java map添加另一个map时候 键值对的类型要一致

  9. 【poj2154】Color Polya定理+欧拉函数

    题目描述 $T$ 组询问,用 $n$ 种颜色去染 $n$ 个点的环,旋转后相同视为同构.求不同构的环的个数模 $p$ 的结果. $T\le 3500,n\le 10^9,p\le 30000$ . 题 ...

  10. 自动化生成html报告

    package Utils; import java.io.File; import java.util.Date; import org.apache.commons.lang3.time.Date ...