首页 > 其他分享 >2022.11.04

2022.11.04

时间:2022-11-04 19:37:39浏览次数:96  
标签:code 04 int 短路 分治 mid 矩形 2022.11

2022.11.04

P3350

非常风骚的一道分治。
这其实是我做的第一道在网格图上跑最短路的题,也让我学到了一些小技巧:

  1. 给网格图附上编号

    code
    int id(int x, int y){return (x - 1) * m + y;}
    

    这样就可以用链式前向星愉快存边和跑 \(dijkstra\) 了。

  2. 分治过程中可以用一个临时数组给要分类的数组作临时存储再复制回原数组

    code
    for(int i = ql; i <= qr; ++i)
        if(Q[i].y1 < mid && Q[i].y2 < mid)T[++L] = Q[i];
        else if(Q[i].y1 > mid && Q[i].y2 > mid)T[--R] = Q[i];
    int pos = L;
    for(int i = ql; i <= L; ++i)Q[i] = T[i];
    for(int i = R; i <= qr; ++i)Q[++pos] = T[i];
    solve(u, d, l, mid - 1, ql, L);
    solve(u, d, mid + 1, r, L + 1, pos);
    

    阿其实这个在之前某次 \(\color{Black}{C}\color{Red}{laris}\) 的题目中有出现过。


接下来正题,让我们来看看这个神奇的分治:
将当前矩形拦腰截开,把它较长的那一边切成两半,就像这样:

if(down - up >= right - left){
    int mid = up + down >> 1;
    ···
}else{
    int mid = left + right >> 1;
    ···
}

然后再从这条 \(mid\) 上的每一个点出发跑一次单源最短路,范围是当前的整个矩形(而不是切出来的部分),然后将整个矩形范围内的询问答案更新一遍。

code
for(int i = l; i <= r; ++i){//这是分成上、下两部分的例子
    dij(u, d, l, r, id(mid, i));
    for(int i = ql; i <= qr; ++i)
        ans[Q[i].id] = Min(ans[Q[i].id], dis[Q[i].p1] + dis[Q[i].p2]);
}

我们可以将范围内的询问分类讨论一下:

  1. 询问的两个点在 \(mid\) 一侧
    • 两点的最短路会经过 \(mid\) :
      会在上面的答案大更新中被更新一次。
    • 两点最短路不经过 \(mid\) :
      没有关系,矩形会继续分割下去,它们两个总能被更新掉。
  2. 询问的两个点在 \(mid\) 两侧
    那么就不用多说,直接就是答案了。

更新完当前矩阵后,继续分治下去,直到边界不合法,这题就做完了。
那么关于时间复杂度,简单理解一下,算它跑满好了:总共跑了 \(n\cdot m\) 次 \(dijkstra\),但是基本上每次涉及的范围都减半了,大概就相当于整个大的 \(n\cdot m\) 的矩形被分了几次(一次指的是每个部分都砍成两半),就跑了几遍范围为 \(n\cdot m\) 的 \(dijkstra\)。至于具体的证明,不如康康介个blog

标签:code,04,int,短路,分治,mid,矩形,2022.11
From: https://www.cnblogs.com/cotsheep/p/16858873.html

相关文章

  • LNK4042 object specified more than once; extras ignored的解决方法
    C++项目编译时遇到警告(warning)LNK4042objectspecifiedmorethanonce;extrasignored 原因某个头文件(.h)的文件类型(itemtype)被设置成了C/C++compiler,这个类......
  • Nexus RCE CVE-2018-16621/CVE-2020-10204
    POST/service/extdirectHTTP/1.1Host:xxxxxxxxxUser-Agent:Mozilla/5.0(WindowsNT10.0;Win64;x64;rv:106.0)Gecko/20100101Firefox/106.0Accept:*/*Accep......
  • 22.11.04
    1、高斯白噪声高斯白噪声,幅度分布服从高斯分布,功率谱密度服从均匀分布白噪声,如同白光一样,是所有颜色的光叠加而成,不同颜色的光本质区别是的它们的频率各不相同(如红色光波......
  • OpenJudge 1.7.04 石头剪子布
    04:石头剪子布总时间限制:1000ms内存限制:65536kB描述石头剪子布,是一种猜拳游戏。起源于中国,然后传到日本、朝鲜等地,随着亚欧贸易的不断发展它传到了欧洲,到了近现代......
  • ubuntu16.04安装mmdetection库
    一,前言1.1,更新pip和conda下载源1.2,查看conda和pip版本二,MMDetection简介三,MMDetection安装3.1,依赖环境3.2,安装过程记录1,安装操作系统+cuda2,安装An......
  • Linux Ubuntu 20.04 —添加开机启动(服务/脚本)
    本文章向大家介绍LinuxUbuntu20.04—添加开机启动(服务/脚本),主要包括LinuxUbuntu20.04—添加开机启动(服务/脚本)使用实例、应用技巧、基本知识点总结和需要注意事......
  • 【单片机/嵌入式】【梁山派】学习日志04:寄存器点灯
    一、寄存器点亮LED1.1配置流程一般我们使用GPIO的端口,都需要有以下几个步骤。(1)开启GPIO的端口时钟(2)配置GPIO的模式(3)配置GPIO的输出从LED介绍那一章节我们了解到LED1......
  • Java学习——11.04
    因为昨天学的有点少,上不了台面,所以和今天的一起写,当然还可能是自己太懒了,昨天的没记住,于是又看了一遍。1.变量:局部变量(和C一样的)实例变量(加new引用文件名创建函数......
  • 【FAQ】调用华为云空间文件管理接口出现"errorCode":"21000403"
    ​ 1、问题描述调用华为云空间文件管理接口,总是返回错误,{"error":{"errorDetail":[{"domain":"global","reason":"authError","description":"AccessForbidden","error......
  • ubuntu20.04 从安装 kvm、qemu、libvirt 到进入虚拟机
    安装环境可行性检测验证CPU是否支持硬件虚拟化grep-Eoc'(vmx|svm)'/proc/cpuinfo//数字大于0,则代表CPU支持硬件虚拟化,反之则不支持检查VT是否在BIOS中启用a......