题目传送门

题目大意

给出 \(n\) 做城市,每座城市都有横纵坐标 \(x,y\)。现在给出 \(m\) 个限制 \(p,t,l,r,d,u\),表示从 \(p\) 城市出发,可以花费 \(t\) 走到 \(l\le x\le r,d\le y\le u\) 的一座城市。

问,从城市 1 出发走到每座城市的最小花费是多少?

\(n\le 7\times 10^4,m\le 1.5\times 10^5\)

思路

这道题自己只做出来 \(76\) 分,剩下的感觉还是比较妙吧?

首先不难看出,我们可以用 K-D Tree 优化建图,大概意思就是 K-D Tree 上的虚点连对应的实点,虚点连儿子,每个点连可以到的点的虚点,然后跑最短路算法就好了。

这样做可以看出边数是 \(m\sqrt n\) 级别的,所以时间复杂度是 \(\Theta(m\sqrt n\log n)\),但是空间复杂度也是 \(m\sqrt n\) 级别的。

我们其实可以考虑不建边,每次在 K-D Tree 上进行松弛操作。这样空间复杂度就降到了 \(n+m\)。

\(\texttt{Code}\)

#include <bits/stdc++.h>
using namespace std; #define Int register int
#define MAXN 140005 template <typename T> inline void read (T &t){t = 0;char c = getchar();int f = 1;while (c < '0' || c > '9'){if (c == '-') f = -f;c = getchar();}while (c >= '0' && c <= '9'){t = (t << 3) + (t << 1) + c - '0';c = getchar();} t *= f;}
template <typename T,typename ... Args> inline void read (T &t,Args&... args){read (t);read (args...);}
template <typename T> inline void write (T x){if (x < 0){x = -x;putchar ('-');}if (x > 9) write (x / 10);putchar (x % 10 + '0');} int n,m,w,h,rt,cut; struct Vector{
int x[2],pos;
bool operator < (const Vector &p)const{return x[cut] < p.x[cut];}
}city[MAXN],pnt[MAXN];
int mi[MAXN][2],mx[MAXN][2],lson[MAXN],rson[MAXN]; void Mx (int &a,int b){a = max (a,b);}
void Mi (int &a,int b){a = min (a,b);}
void Pushup (int x){
mi[x][0] = mx[x][0] = city[x].x[0],mi[x][1] = mx[x][1] = city[x].x[1];
if (lson[x]) for (Int i = 0;i < 2;++ i) Mi (mi[x][i],mi[lson[x]][i]),Mx (mx[x][i],mx[lson[x]][i]);
if (rson[x]) for (Int i = 0;i < 2;++ i) Mi (mi[x][i],mi[rson[x]][i]),Mx (mx[x][i],mx[rson[x]][i]);
} int build (int l,int r,int k){
if (l > r) return 0;
int mid = (l + r) >> 1,now = mid;cut = k;
nth_element (city + l,city + mid,city + r + 1);
if (l == r) return Pushup (now),now;
else{
lson[now] = build (l,mid - 1,k ^ 1);
rson[now] = build (mid + 1,r,k ^ 1);
}
Pushup (now);
return now;
} int dist[MAXN];
bool vis[MAXN];
#define PII pair<int,int>
priority_queue <PII,vector <PII>,greater <PII> > q; void Relax (int u,int w){
if (dist[u] > w){
dist[u] = w;
if (!vis[u]) q.push (make_pair (dist[u],u));
}
} void SolveE (int now,int x1,int x2,int y1,int y2,int ind,int t){
if (!now) return ;
if (mi[now][0] > x2 || mx[now][0] < x1 || mi[now][1] > y2 || mx[now][1] < y1) return ;
if (mi[now][0] >= x1 && mx[now][0] <= x2 && mi[now][1] >= y1 && mx[now][1] <= y2){
Relax (now,dist[ind] + t);
return ;
}
if (city[now].x[0] >= x1 && city[now].x[0] <= x2 && city[now].x[1] >= y1 && city[now].x[1] <= y2)
Relax (city[now].pos,dist[ind] + t);
SolveE (lson[now],x1,x2,y1,y2,ind,t);
SolveE (rson[now],x1,x2,y1,y2,ind,t);
return ;
} struct node{int L,R,U,D,T;};
vector <node> G[MAXN]; void Dijkstra (int s){
memset (dist,0x7f,sizeof (dist));
dist[s] = 0,vis[s] = 1;
while (!q.empty()) q.pop ();
q.push (make_pair (0,s));
while (!q.empty()){
PII now = q.top ();q.pop ();int u = now.second;vis[u] = 1;
if (dist[u] != now.first) continue;
if (u > n) for (node to : G[u - n]) SolveE (rt,to.L,to.R,to.D,to.U,u,to.T);
else Relax (lson[u],dist[u]),Relax (rson[u],dist[u]),Relax (city[u].pos,dist[u]);
}
} signed main(){
read (n,m,w,h);
for (Int i = 1;i <= n;++ i) read (city[i].x[0],city[i].x[1]),city[i].pos = n + i;
rt = build (1,n,0);for (Int i = 1;i <= m;++ i){
int p,t,l,r,d,u;read (p,t,l,r,d,u);
G[p].push_back (node {l,r,u,d,t});
}
Dijkstra (n + 1);
for (Int i = 2;i <= n;++ i) write (dist[n + i]),putchar ('\n');
return 0;
}

题解 [NOI2019]弹跳的更多相关文章

  1. 【题解】Luogu P5471 [NOI2019]弹跳

    原题传送门 先考虑部分分做法: subtask1: 暴力\(O(nm)\)枚举,跑最短路 subtask2: 吧一行的点压到vector中并排序,二分查找每一个弹跳装置珂以到达的城市,跑最短路 sub ...

  2. [NOI2019] 弹跳

    题意: 给你平面上的$n$个点,共有$m$个弹跳装置. 每个弹跳装置可以从点$p_{i}$以$t_{i}$的代价跳到矩形$(L_{i},D_{i}),(R_{i},U_{i})$中的任何一个点. 现在 ...

  3. 洛谷 P5471 - [NOI2019] 弹跳(二维线段树优化建图+堆优化存边)

    题面传送门 一道非常有意思的题(大概可以这么形容?) 首先看到这类一个点想一个区域内连边的题目可以很自然地想到线段树优化建图,只不过这道题是二维的,因此需要使用二维线段树优化建图,具体来说,我们外层开 ...

  4. [NOI2019]弹跳(KD-Tree/四分树/线段树套平衡树 优化建图+Dijkstra)

    本题可以用的方法很多,除去以下三种我所知道的就还有至少三种. 方法一:类似线段树优化建图,将一个平面等分成四份(若只有一行或一列则等分成两份),然后跑Dijkstra即可.建树是$O(n\log n) ...

  5. luogu P5471 [NOI2019]弹跳

    luogu 因为是一个点向矩形区域连边,所以可以二维数据结构优化连边,但是会MLE.关于维护矩形的数据结构还有\(KD-Tree\),所以考虑\(KDT\)优化连边,空间复杂度\(m\sqrt n\) ...

  6. luogu 5471 [NOI2019]弹跳 KDtree + Dijkstra

    题目链接 第一眼就是 $KDtree$ 优化建图然而,空间只有 $128mb$,开不下   时间不吃紧,考虑直接跑 $Dijkstra$ $Dijkstra$ 中存储的是起点到每个输入时给出的矩阵的最 ...

  7. p5471 [NOI2019]弹跳

    分析 代码 #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define ...

  8. [NOI2019]弹跳(KD-Tree)

    被jump送退役了,很生气. 不过切了这题也进不了队,行吧. 退役后写了一下,看到二维平面应该就是KD树,然后可以在KD树上做最短路,然后建立堆和KDTree.然后每次更新则是直接把最短路上的节点删掉 ...

  9. 【NOI2019】弹跳(KDT优化建图)

    Description 平面上有 \(n\) 个点,分布在 \(w \times h\) 的网格上.有 \(m\) 个弹跳装置,由一个六元组描述.第 \(i\) 个装置有参数:\((p_i, t_i, ...

随机推荐

  1. 虚拟dom?diff算法?key?Vue原理的核心三问?打包教你搞定。

    为什么需要虚拟DOM 先介绍浏览器加载一个HTML文件需要做哪些事,帮助我们理解为什么我们需要虚拟DOM.webkit引擎的处理流程,如下图所示: 所有浏览器的引擎工作流程都差不多,如上图大致分5步: ...

  2. ROS catkin_make error Could not find a package configuration file provided by "actionlib_msgs"

    在使用ROS catkin_make编译的时候,出现类似如下错误 CMake Error at /opt/ros/kinetic/share/catkin/cmake/catkinConfig.cma ...

  3. 使用ECharts绘制网址径向树状图

    an.rustfisher.com有很多内容,很多页面.如果用一个树状图把所有页面展示出来会是什么效果? 第一时间想到了ECharts. 最后效果: https://an.rustfisher.com ...

  4. BeanUtils基本使用方法与原理

    使用BeanUtils的原因 因为setProperty是JSP中的标签,因此使用model 2模式JSP+Servlet+JavaBean的时候,JSP将form提交给Servlet程序,而Serv ...

  5. 10分钟学会Visual Studio将自己创建的类库打包到NuGet进行引用(net,net core,C#)

    前言 NuGet就是一个包(package)管理平台,确切的说是 .net平台的包管理工具,它提供了一系列客户端用于生成,上传和使用包(package),以及一个用于存储所有包的中心库. 对于一个现代 ...

  6. Java基础(四)——抽象类和接口

    一.抽象类 1.介绍 使用关键字 abstract 定义抽象类. abstract定义抽象方法,只有声明,不用实现. 包含抽象方法的类必须定义为抽象类. 抽象类中可以有普通方法,也可以有抽象方法. 抽 ...

  7. 羽夏笔记——Win32(非WinAPI)

    写在前面   本笔记是由本人独自整理出来的,图片来源于网络.本人非计算机专业,可能对本教程涉及的事物没有了解的足够深入,如有错误,欢迎批评指正. 如有好的建议,欢迎反馈.码字不易,如果本篇文章有帮助你 ...

  8. adb 常用命令大全(5)- 日志相关

    前言 Android 系统的日志分为两部分 底层的 Linux 内核日志输出到 /proc/kmsg Android 的日志输出到 /dev/log 语法格式 adb logcat [<opti ...

  9. Linux原始套接字抓取底层报文

    1.原始套接字使用场景 我们平常所用到的网络编程都是在应用层收发数据,每个程序只能收到发给自己的数据,即每个程序只能收到来自该程序绑定的端口的数据.收到的数据往往只包括应用层数据,原有的头部信息在传递 ...

  10. [源码解析] 深度学习流水线并行 PipeDream(5)--- 通信模块

    [源码解析] 深度学习流水线并行 PipeDream(5)--- 通信模块 目录 [源码解析] 深度学习流水线并行 PipeDream(5)--- 通信模块 0x00 摘要 0x01 前言 0x02 ...