越野赛车问题

2023-12-24 13:40
文章标签 问题 越野赛

本文主要是介绍越野赛车问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

越野赛车问题

小 $H$ 是一位优秀的越野赛车女选手。现在她准备在 $A$ 山上进行赛车训练。

$A$ 山上一共有 $n$ 个广场,编号依次为 $1$ 到 $n$ ,这些广场之间通过 $n-1$ 条双向车道直接或间接地连接在一起。对于每条车道 $i$ ,可以用四个正整数 $u_i,v_i,l_i,r_i$ 描述,表示车道连接广场 $u_i$ 和 $v_i$ ,其速度承受区间为 $[l_i,r_i]$,即汽车必须以不小于 $l_i$ 且不大于 $r_i$ 的速度经过车道 $i$ 。

小 $H$ 计划进行 $m$ 次训练,每次她需要选择 $A$ 山上的一条简单路径,然后在这条路径上行驶。但小 $H$ 不喜欢改变速度,所以每次训练时的车速都是固定的。

现在小 $H$ 告诉你她在 $m$ 次训练中计划使用的车速,请帮助她对于每次训练,找到一条合法的路径(车速在所有车道的速度承受区间的交集内),使得路径上经
过的车道数最大。


Sol

考虑线段树分治。按速度开线段树,把边加进去。

查询时用一个并查集维护当前树的直径。

画画图可以发现,合并完的两棵树的直径,一定是两棵树的直径各取一段拼在一起的来,或者是其中一棵树的直径。

那么我们再维护端点,也就可以维护答案了。

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#define maxn 140005
using namespace std;
int n,m,head[maxn],tot,st[maxn][21],deep[maxn],fi[maxn],sc;
int ans,qans[maxn],f[maxn],sz[maxn];
struct haha{vector<int>u,v;
}tr[maxn*4];
struct node{int v,nex;}e[maxn];
struct Node{int x,y;}c[maxn];
struct nod{int v,id,idf;int num,ans;Node df;
}q[maxn]; 
vector<nod>s;
bool cmp(nod a,nod b){return a.v<b.v;}
void add(int k,int l,int r,int li,int ri,int u,int v){if(l>=li&&r<=ri){tr[k].u.push_back(u);tr[k].v.push_back(v);return;}int mid=l+r>>1;if(li<=mid)add(k*2,l,mid,li,ri,u,v);if(ri>mid)add(k*2+1,mid+1,r,li,ri,u,v);
}
void lj(int t1,int t2){e[++tot].v=t2;e[tot].nex=head[t1];head[t1]=tot;
}
void dfs(int k,int fa){fi[k]=++sc;deep[k]=deep[fa]+1;st[sc][0]=deep[k];for(int i=head[k];i;i=e[i].nex){if(e[i].v==fa)continue;dfs(e[i].v,k);st[++sc][0]=deep[k];}
}
int getf(int k){return f[k]==k?k:getf(f[k]);}
int dis(int x,int y){int l=fi[x],r=fi[y];if(l>r)swap(l,r);int t=log2(r-l+1);int d=min(st[l][t],st[r-(1<<t)+1][t]);return deep[x]+deep[y]-2*d;
}
void hb(int k){int siz=tr[k].u.size();for(int i=0;i<siz;i++){int u=tr[k].u[i],v=tr[k].v[i];int fu=getf(u),fv=getf(v);if(sz[fu]<sz[fv])swap(fu,fv),swap(u,v);nod t;t.id=fv;t.idf=fu;t.v=sz[fv];t.df=c[fu];t.num=k;s.push_back(t);sz[fu]+=sz[fv];f[fv]=fu;int x1=dis(c[fu].x,u)>dis(c[fu].y,u)?c[fu].x:c[fu].y;int x2=dis(c[fv].x,v)>dis(c[fv].y,v)?c[fv].x:c[fv].y;if(dis(x1,x2)>dis(c[fu].x,c[fu].y))c[fu]=(Node){x1,x2};if(dis(c[fv].x,c[fv].y)>dis(c[fu].x,c[fu].y))c[fu]=c[fv];ans=max(ans,dis(c[fu].x,c[fu].y));}
}
void turn(int k){int siz=s.size();for(int i=siz-1;i>=0;i--){if(s[i].num!=k)break;int fu=s[i].idf,fv=s[i].id;f[fv]=fv;sz[fu]-=s[i].v;c[fu]=s[i].df;s.pop_back();}
}
void solve(int k,int l,int r,int ql,int qr){if(ql>qr)return;int la=ans;hb(k);if(l==r){for(int i=ql;i<=qr;i++)qans[q[i].id]=ans;ans=la;turn(k);return;}int mid=l+r>>1;int sp;for(sp=ql-1;q[sp+1].v<=mid&&sp<qr;sp++);solve(k*2,l,mid,ql,sp);solve(k*2+1,mid+1,r,sp+1,qr);ans=la;turn(k);
}
int main(){cin>>n>>m;for(int i=1,u,v,t1,t2;i<n;i++){scanf("%d%d%d%d",&u,&v,&t1,&t2);add(1,1,n,t1,t2,u,v);lj(u,v);lj(v,u);}dfs(1,0);for(int j=1;j<=20;j++)for(int i=1;i+(1<<j)<=sc+1;i++)st[i][j]=min(st[i][j-1],st[i+(1<<j-1)][j-1]);for(int i=1;i<=m;i++){scanf("%d",&q[i].v);q[i].id=i;}sort(q+1,q+m+1,cmp);for(int i=1;i<=n;i++)f[i]=i,c[i].x=c[i].y=i;solve(1,1,n,1,m);for(int i=1;i<=m;i++)cout<<qans[i]<<endl;return 0;
}
View Code

这篇关于越野赛车问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/531960

相关文章

mybatis和mybatis-plus设置值为null不起作用问题及解决

《mybatis和mybatis-plus设置值为null不起作用问题及解决》Mybatis-Plus的FieldStrategy主要用于控制新增、更新和查询时对空值的处理策略,通过配置不同的策略类型... 目录MyBATis-plusFieldStrategy作用FieldStrategy类型每种策略的作

linux下多个硬盘划分到同一挂载点问题

《linux下多个硬盘划分到同一挂载点问题》在Linux系统中,将多个硬盘划分到同一挂载点需要通过逻辑卷管理(LVM)来实现,首先,需要将物理存储设备(如硬盘分区)创建为物理卷,然后,将这些物理卷组成... 目录linux下多个硬盘划分到同一挂载点需要明确的几个概念硬盘插上默认的是非lvm总结Linux下多

Python Jupyter Notebook导包报错问题及解决

《PythonJupyterNotebook导包报错问题及解决》在conda环境中安装包后,JupyterNotebook导入时出现ImportError,可能是由于包版本不对应或版本太高,解决方... 目录问题解决方法重新安装Jupyter NoteBook 更改Kernel总结问题在conda上安装了

pip install jupyterlab失败的原因问题及探索

《pipinstalljupyterlab失败的原因问题及探索》在学习Yolo模型时,尝试安装JupyterLab但遇到错误,错误提示缺少Rust和Cargo编译环境,因为pywinpty包需要它... 目录背景问题解决方案总结背景最近在学习Yolo模型,然后其中要下载jupyter(有点LSVmu像一个

解决jupyterLab打开后出现Config option `template_path`not recognized by `ExporterCollapsibleHeadings`问题

《解决jupyterLab打开后出现Configoption`template_path`notrecognizedby`ExporterCollapsibleHeadings`问题》在Ju... 目录jupyterLab打开后出现“templandroidate_path”相关问题这是 tensorflo

如何解决Pycharm编辑内容时有光标的问题

《如何解决Pycharm编辑内容时有光标的问题》文章介绍了如何在PyCharm中配置VimEmulator插件,包括检查插件是否已安装、下载插件以及安装IdeaVim插件的步骤... 目录Pycharm编辑内容时有光标1.如果Vim Emulator前面有对勾2.www.chinasem.cn如果tools工

最长公共子序列问题的深度分析与Java实现方式

《最长公共子序列问题的深度分析与Java实现方式》本文详细介绍了最长公共子序列(LCS)问题,包括其概念、暴力解法、动态规划解法,并提供了Java代码实现,暴力解法虽然简单,但在大数据处理中效率较低,... 目录最长公共子序列问题概述问题理解与示例分析暴力解法思路与示例代码动态规划解法DP 表的构建与意义动

Java多线程父线程向子线程传值问题及解决

《Java多线程父线程向子线程传值问题及解决》文章总结了5种解决父子之间数据传递困扰的解决方案,包括ThreadLocal+TaskDecorator、UserUtils、CustomTaskDeco... 目录1 背景2 ThreadLocal+TaskDecorator3 RequestContextH

关于Spring @Bean 相同加载顺序不同结果不同的问题记录

《关于Spring@Bean相同加载顺序不同结果不同的问题记录》本文主要探讨了在Spring5.1.3.RELEASE版本下,当有两个全注解类定义相同类型的Bean时,由于加载顺序不同,最终生成的... 目录问题说明测试输出1测试输出2@Bean注解的BeanDefiChina编程nition加入时机总结问题说明

关于最长递增子序列问题概述

《关于最长递增子序列问题概述》本文详细介绍了最长递增子序列问题的定义及两种优化解法:贪心+二分查找和动态规划+状态压缩,贪心+二分查找时间复杂度为O(nlogn),通过维护一个有序的“尾巴”数组来高效... 一、最长递增子序列问题概述1. 问题定义给定一个整数序列,例如 nums = [10, 9, 2