传送门:Speed

题目大意

给一棵n个点的无根树,每条树边i给出li和ri表示速度在[li,ri]内才能通过这条边。

现在有m个询问,每个询问给出一个速度x,求以x的速度(不能改变)能在树上通过的路径长度的最大值(起点和终点任意)。

n,m<=70000;1<=li,ri<=n;

来源&写因

这题是在dalao们成外集训最后一场考试的T3,听说当时无人AC,确实挺难的,我自问也只会写n^2暴力。

正解充分运用了线段树的性质,前些天新学的线段树优化建图也有异曲同工之妙,感觉领悟到了线段树的一些精髓,所以来写篇题解。

题解

m跟n同级,也就是说得求出速度为1~n时的答案,再O(1)回答询问。

对于一个速度x,如果我们只在树上留下速度区间包含x的边,删去其它边,会得到一个森林,答案就是其中最长直径。那么我们肯定要考虑动态维护一个森林的最长直径,也就是说,维护其中每一个连通块的最长链,支持加边操作。并查集加树的直径的性质[1]可以轻松实现。

问题是哪些区间包含x呢?

设n=8,x=3

发现包含x的区间即为包含[3]或[3,4]或[1,4]的所有区间。

这启发我们用线段树做。

首先对于线段树上的每一个节点node,存下所有包含了node所代表区间的边(直接用链表存)。

然后求答案时遍历一遍线段树,每走到一个节点node,就施加node的链表里存的边的影响,而每离开一个节点node,就撤销node的链表里存的边的影响。这样子当遍历到线段树的一个叶子节点时,设l=r=x,我们恰好施加了所有包含x的边的影响,答案就有了。

注意到我们需要撤销影响,可持久化并查集,其实用个栈存操作信息,回溯时怎么改的就怎么改回去就好了,可以发现进栈元素个数是nlogn的。但是这样做的话并查集就绝不能路径压缩了,于是复杂度就变得相当玄学,然而实测即使是在链的情况也跑得飞起==

//upd:其实可以按秩合并,能保证一次log的复杂度。

自然语言太无力了,还是看代码吧。

#include<bits/stdc++.h>
using namespace std;
const int N=70005,M=N*20;
inline int read(){
int x=0,w=0;char ch=0;
while(!isdigit(ch)) w|=ch=='-',ch=getchar();
while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return w?-x:x;
}
vector<int> to[N];
namespace sp{
int dep[N],fa[N],sz[N],son[N],top[N];
void dfs1(int x,int pre){
dep[x]=dep[pre]+1;fa[x]=pre;sz[x]=1;
for(int i=0;i<to[x].size();++i){
int &y=to[x][i];
if(y==pre) continue;
dfs1(y,x);
sz[x]+=sz[y];
if(sz[y]>sz[son[x]]) son[x]=y;
}
}
void dfs2(int x,int pre){
top[x]=pre;
if(son[x]) dfs2(son[x],pre);
for(int i=0;i<to[x].size();++i){
int &y=to[x][i];
if(y==son[x]||y==fa[x]) continue;
dfs2(y,y);
}
}
int lca(int x,int y){
while(top[x]^top[y]){
if(dep[top[x]]<dep[top[y]]) x^=y^=x^=y;
x=fa[top[x]];
}
return dep[x]<dep[y]?x:y;
}
int dist(int x,int y){return dep[x]+dep[y]-(dep[lca(x,y)]<<1);}
}
int n,m,cur=0;
namespace st{
int fa[N],l[N],r[N],f[N];
void init(){
for(int i=1;i<=n;++i) fa[i]=l[i]=r[i]=i,f[i]=0;
}
inline int find(int x){return x==fa[x]?x:find(fa[x]);}
struct opt{
int id,x,val;
}q[N<<2];
using sp::dist;
void merge(int x,int y,int &ans){
x=find(x),y=find(y);
if(x==y) return ;
int res=0,nl,nr,t=-1;
if(f[x]>res) nl=l[x],nr=r[x],res=f[x];
if(f[y]>res) nl=l[y],nr=r[y],res=f[y];
t=dist(l[x],l[y]);
if(t>res) nl=l[x],nr=l[y],res=t;
t=dist(r[x],r[y]);
if(t>res) nl=r[x],nr=r[y],res=t;
t=dist(l[x],r[y]);
if(t>res) nl=l[x],nr=r[y],res=t;
t=dist(r[x],l[y]);
if(t>res) nl=r[x],nr=l[y],res=t;
q[++cur]=(opt){0,y,0};
q[++cur]=(opt){1,x,l[x]};
q[++cur]=(opt){2,x,r[x]};
q[++cur]=(opt){3,x,f[x]};
fa[y]=x,l[x]=nl,r[x]=nr,f[x]=res;
ans=max(ans,res);
}
void retrace(int tim){
while(cur>tim){
switch(q[cur].id){
case 0:fa[q[cur].x]=q[cur].x;break;
case 1:l[q[cur].x]=q[cur].val;break;
case 2:r[q[cur].x]=q[cur].val;break;
case 3:f[q[cur].x]=q[cur].val;break;
}
--cur;
}
}
}
namespace sg{
int tot,tail[N<<2];
struct edge{
int u,v,last;
}e[M];
#define tl id<<1
#define tr id<<1|1
#define mid (l+r>>1)
#define lson tl,l,mid
#define rson tr,mid+1,r
void update(int id,int l,int r,int ll,int rr,int u,int v){
if(ll<=l&&r<=rr){
e[++tot]=(edge){u,v,tail[id]};
tail[id]=tot;
return ;
}
if(rr<=mid) update(lson,ll,rr,u,v);
else if(ll>mid) update(rson,ll,rr,u,v);
else update(lson,ll,rr,u,v),update(rson,ll,rr,u,v);
}
int ans[N];
void solve(int id,int l,int r,int res){
int tim=cur;
for(int p=tail[id];p;p=e[p].last) st::merge(e[p].u,e[p].v,res);
if(l==r){
ans[l]=res;
st::retrace(tim);
return ;
}
solve(lson,res),solve(rson,res);
st::retrace(tim);
}
}
int main(){
n=read(),m=read();
for(int i=1,u,v,l,r;i<n;++i){
u=read(),v=read(),l=read(),r=read();
to[u].push_back(v),to[v].push_back(u);
sg::update(1,1,n,l,r,u,v);
}
sp::dfs1(1,0);sp::dfs2(1,1);
st::init();
sg::solve(1,1,n,0);
while(m--) printf("%d\n",sg::ans[read()]);
return 0;
}

  1. 设树A和树B,树A直径的端点为la和ra,树B直径的端点为lb和rb。在A和B之间连一条边后,得到的新树的直径的端点一定是la,ra,lb,rb中的两个。 ↩︎

Speed的更多相关文章

  1. hdu FatMouse's Speed 动态规划DP

    动态规划的解决方法是找到动态转移方程. 题目地址:http://acm.hdu.edu.cn/game/entry/problem/show.php?chapterid=3&sectionid ...

  2. LYDSY模拟赛day2 Dash Speed

    /* 弃坑 */ #include<cstdio> #include<algorithm> using namespace std; ,M=N*; ],nxt[N<< ...

  3. FatMouse's Speed——J

    J. FatMouse's Speed FatMouse believes that the fatter a mouse is, the faster it runs. To disprove th ...

  4. OpenVZ VPS加速方案–Final Speed

    body,td { font-family: 微软雅黑; font-size: 10pt }   OpenVZ VPS加速方案–Final Speed OpenVZ VPS加速方案–Final Spe ...

  5. UNITY3D单词学习 speed和velocity的区别

    在日常用语中,这两个词没有区别,可以通用. 而在物理学里,velocity 是一个矢量(vector quantity)表示起点与终点间直线距离的长度除以所用时间所得的量,并注明方向;而 speed ...

  6. HD1160FatMouse's Speed(最长单调递增子序列)

    FatMouse's Speed Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  7. HDU 1160 FatMouse's Speed(要记录路径的二维LIS)

    FatMouse's Speed Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  8. 论文笔记之:Speed Up Tracking by Ignoring Features

    Speed Up Tracking by Ignoring Features CVPR 2014 Abstract:本文提出一种特征选择的算法,来实现用最"精简"的特征以进行目标跟 ...

  9. Website Speed Optimization Guide for Google PageSpeed Rules

    原链接地址:http://www.artzstudio.com/2016/07/website-speed-optimization-guide-for-google-pagespeed-rules/ ...

  10. 3.openssl speed和openssl rand

    (1).openssl speed 测试加密算法的性能. 支持的算法有: openssl speed [md2] [mdc2] [md5] [hmac] [sha1] [rmd160] [idea-c ...

随机推荐

  1. vue进阶:基于vue-cli创建项目(搭建手脚架)

    vue-cli安装.创建项目 基于vue-cli创建的项目进行开发 使用vue-cli图形化界面搭建项目 插件与工具 一.vue-cli简介.安装.创建项目 Vue-cli是基于Vue.js进行快速开 ...

  2. Spring整合Hessian的使用

    该文章转赞自  https://www.cnblogs.com/ontheroad_lee/p/3797239.htm 个人感觉写的非常好,刚学习,先记录下来 1.1     Hessian简介 He ...

  3. 简单粗暴 每个servlet之前都插入一段代码解决 乱码问题

    response.setHeader("content-type", "text/html;charset=UTF-8"); response.setChara ...

  4. 数据总线&地址总线&控制总线

    数据总线 (1) 是CPU与内存或其他器件之间的数据传送的通道. (2)数据总线的宽度决定了CPU和外界的数据传送速度. (3)每条传输线一次只能传输1位二进制数据.eg: 8根数据线一次可传送一个8 ...

  5. MySQL之concat、concat_ws、group_concat

    concat(str1, str2, ...)  返回结果为连接一起的字符串. concat_ws(separator, str1, str2, ...) 同concat,但是可以指定连接符,sepa ...

  6. 1.Nginx安装

    1.Nginx安装配置 Nginx("engine x")是一款是由俄罗斯的程序设计师Igor Sysoev所开发的高性能 Web和 反向代理服务器,也是一个 IMAP/POP3/ ...

  7. C++面试高频题

    作者:守望者1028链接:https://www.nowcoder.com/discuss/55353来源:牛客网 面试高频题: 校招过程中参考过牛客诸位大佬的面经,但是具体哪一块是参考谁的我也忘记了 ...

  8. 洛谷 P2939 [USACO09FEB]改造路Revamping Trails

    题意翻译 约翰一共有N)个牧场.由M条布满尘埃的小径连接.小径可 以双向通行.每天早上约翰从牧场1出发到牧场N去给奶牛检查身体. 通过每条小径都需要消耗一定的时间.约翰打算升级其中K条小径,使之成为高 ...

  9. Tourist's Notes CodeForces - 538C (贪心)

    A tourist hiked along the mountain range. The hike lasted for n days, during each day the tourist no ...

  10. ribbon负载均衡循环策略源码

    (原) 在用ribbon负载均衡取eureka注册中心中的地址时,默认采用循环策略,例如商品服务有3个,分别为URL1,URL2,URL3,那么在客户端第一次取时,会取到URL1,第二次取时取到URL ...