[NOI2019] 弹跳
题意:
给你平面上的$n$个点,共有$m$个弹跳装置。
每个弹跳装置可以从点$p_{i}$以$t_{i}$的代价跳到矩形$(L_{i},D_{i}),(R_{i},U_{i})$中的任何一个点。
现在请你对于每座城市求出从1号点跳到它的最小代价。
$n\leq 70000,m\leq 150000$。
题解:不把边建出来的$KD-tree$优化建图。
看一眼就知道$KD-tree$优化建图,但如果把所有边都建出来就爆炸了。
设原图上的点是实点,$KD-tree$上的点(代表一个实点和一个矩形)是虚点。
那么在$Dijkstra$到每个点的时候:
- 若是实点,在$KD-tree$上查找能连的虚点/实点并向其连带权边。
- 若是虚点,向它的两个儿子和它对应的实点连权为0的边。
时间复杂度$O(m\sqrt{n})$,空间复杂度$O(m\sqrt{n})$(实际上只有优先队列可能达到这个空间,其他都是$O(n)$)。
没了。不知道为什么有人写线段树。
代码:
#include<bits/stdc++.h>
#define maxn 200005
#define maxm 500005
#define inf 0x7fffffff
#define ll long long
#define rint register int
#define debug(x) cerr<<#x<<": "<<x<<endl
#define fgx cerr<<"--------------"<<endl
#define dgx cerr<<"=============="<<endl using namespace std;
struct Point{int x[],iid;}p[maxn];
int mx[maxn][],mn[maxn][],id[maxn],ls[maxn],rs[maxn];
int tot,np,dis[maxn<<],vis[maxn<<],tim[maxn];
int L[maxn],R[maxn],D[maxn],U[maxn];
struct node{int u,d;bool operator<(const node &b)const{return d>b.d;}};
priority_queue<node> q; vector<int> vc[maxn]; inline int read(){
int x=,f=; char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-;
for(;isdigit(c);c=getchar()) x=x*+c-'';
return x*f;
} inline node md(int u,int d){node res;res.u=u,res.d=d;return res;}
inline void upd(int u,int v){if(dis[u]>v){dis[u]=v,q.push(md(u,v));}}
inline bool ok(int xa,int ya,int xb,int yb){return xb<=xa&&ya<=yb;}
inline bool cmp(Point a,Point b){return (!np)?(a.x[]<b.x[]):(a.x[]<b.x[]);}
inline void pushup(int k){
for(rint i=;i<;i++){
mx[k][i]=mn[k][i]=p[id[k]].x[i];
if(ls[k]) mx[k][i]=max(mx[k][i],mx[ls[k]][i]),mn[k][i]=min(mn[k][i],mn[ls[k]][i]);
if(rs[k]) mx[k][i]=max(mx[k][i],mx[rs[k]][i]),mn[k][i]=min(mn[k][i],mn[rs[k]][i]);
}
}
inline int build(int l,int r,int type){
if(l>r) return ;
int mid=l+r>>,k=++tot;
id[k]=mid,np=type;
nth_element(p+l,p+mid,p+r+,cmp);
ls[k]=build(l,mid-,type^);
rs[k]=build(mid+,r,type^);
pushup(k); return k;
}
inline void add(int l,int r,int d,int u,int c,int k){
if(mx[k][]<l || mn[k][]>r || mx[k][]<d || mn[k][]>u) return;
if(ok(mn[k][],mx[k][],l,r)&&ok(mn[k][],mx[k][],d,u)){upd(k,c);return;}
if(ok(p[id[k]].x[],p[id[k]].x[],l,r)&&ok(p[id[k]].x[],p[id[k]].x[],d,u)) upd(p[id[k]].iid,c);
if(ls[k]) add(l,r,d,u,c,ls[k]); if(rs[k]) add(l,r,d,u,c,rs[k]);
} inline void Dijkstra(int s,int n){
memset(vis,,sizeof(vis));
memset(dis,,sizeof(dis));
dis[s]=,q.push(md(s,));
while(!q.empty()){
rint u=q.top().u; q.pop();
if(vis[u]) continue; vis[u]=;
if(u<=n) for(rint i=;i<vc[u].size();i++)
add(L[vc[u][i]],R[vc[u][i]],D[vc[u][i]],U[vc[u][i]],dis[u]+tim[vc[u][i]],n+);
else upd(p[id[u]].iid,dis[u]),upd(ls[u],dis[u]),upd(rs[u],dis[u]);
}
} int main(){
freopen("jump.in","r",stdin);
freopen("jump.out","w",stdout);
int n=read(),m=read(),w=read(),h=read();
for(rint i=;i<=n;i++)
p[i].x[]=read(),p[i].x[]=read(),p[i].iid=i;
tot=n,build(,n,);
for(rint i=;i<=m;i++){
int p=read();tim[i]=read();
L[i]=read(),R[i]=read();
D[i]=read(),U[i]=read();
vc[p].push_back(i);
}
Dijkstra(,n);
for(rint i=;i<=n;i++) printf("%d\n",dis[i]);
return ;
}
D2T1
[NOI2019] 弹跳的更多相关文章
- 【题解】Luogu P5471 [NOI2019]弹跳
原题传送门 先考虑部分分做法: subtask1: 暴力\(O(nm)\)枚举,跑最短路 subtask2: 吧一行的点压到vector中并排序,二分查找每一个弹跳装置珂以到达的城市,跑最短路 sub ...
- 洛谷 P5471 - [NOI2019] 弹跳(二维线段树优化建图+堆优化存边)
题面传送门 一道非常有意思的题(大概可以这么形容?) 首先看到这类一个点想一个区域内连边的题目可以很自然地想到线段树优化建图,只不过这道题是二维的,因此需要使用二维线段树优化建图,具体来说,我们外层开 ...
- [NOI2019]弹跳(KD-Tree/四分树/线段树套平衡树 优化建图+Dijkstra)
本题可以用的方法很多,除去以下三种我所知道的就还有至少三种. 方法一:类似线段树优化建图,将一个平面等分成四份(若只有一行或一列则等分成两份),然后跑Dijkstra即可.建树是$O(n\log n) ...
- luogu P5471 [NOI2019]弹跳
luogu 因为是一个点向矩形区域连边,所以可以二维数据结构优化连边,但是会MLE.关于维护矩形的数据结构还有\(KD-Tree\),所以考虑\(KDT\)优化连边,空间复杂度\(m\sqrt n\) ...
- luogu 5471 [NOI2019]弹跳 KDtree + Dijkstra
题目链接 第一眼就是 $KDtree$ 优化建图然而,空间只有 $128mb$,开不下 时间不吃紧,考虑直接跑 $Dijkstra$ $Dijkstra$ 中存储的是起点到每个输入时给出的矩阵的最 ...
- p5471 [NOI2019]弹跳
分析 代码 #include<bits/stdc++.h> using namespace std; #define fi first #define se second #define ...
- [NOI2019]弹跳(KD-Tree)
被jump送退役了,很生气. 不过切了这题也进不了队,行吧. 退役后写了一下,看到二维平面应该就是KD树,然后可以在KD树上做最短路,然后建立堆和KDTree.然后每次更新则是直接把最短路上的节点删掉 ...
- 题解 [NOI2019]弹跳
题目传送门 题目大意 给出 \(n\) 做城市,每座城市都有横纵坐标 \(x,y\).现在给出 \(m\) 个限制 \(p,t,l,r,d,u\),表示从 \(p\) 城市出发,可以花费 \(t\) ...
- 【NOI2019】弹跳(KDT优化建图)
Description 平面上有 \(n\) 个点,分布在 \(w \times h\) 的网格上.有 \(m\) 个弹跳装置,由一个六元组描述.第 \(i\) 个装置有参数:\((p_i, t_i, ...
随机推荐
- golang多个项目时如何配置GOPATH,使用gb包依赖管理工具,不同项目配置不同的GOPATH的
golang多个项目时如何配置GOPATH,使用gb包依赖管理工具,不同项目配置不同的GOPATH的 1:执行脚本setGoPath.sh#!/bin/bashif [[ $GOPATH =~ .*$ ...
- page的js访问全局变量:app.globalData.openid
page获取app.js:const app = getApp(); page的js访问全局变量(get/set):const app = getApp(); app.globalData.openi ...
- 在 React 项目中引入 GG-Editor 编辑可视化流程
蚂蚁金服数据可视化团队曾经开源了一款G6-Editor,但后来停止了对外支持,学习成本太高 好在后来他们团队的大牛高力结合 React + G6 开源了一个 GG-Editor(其实就是G6-Edit ...
- CATransform3D 特效详解
http://blog.sina.com.cn/s/blog_8f5097be0101b91z.html
- 汇编之JCC指令
版权声明:本文为博主原创文章,转载请附上原文出处链接和本声明.2019-09-06,21:59:16.作者By-----溺心与沉浮----博客园 JCC指令决定它跳不跳转跟别的没关系,只跟EFLAG标 ...
- ptrace函数深入分析
ptrace函数:进程跟踪. 形式:#include<sys/ptrace.h> Int ptrace(int request,int pid,int addr,int data); 概述 ...
- 2.1 Scala语言概述
一.编程范式 命令式编程没有办法充分利用多核CPU: 函数式编程很多变量是不可修改的. 二.Scala简介 特点 scala运行在JVM上,兼容现有的Java程序: 面向对象的编程语言: 一门函数式语 ...
- 201871010105-曹玉中《面向对象程序设计(java)》第十一周学习总结
201871010105-曹玉中<面向对象程序设计(java)>第十一周学习总结 项目 内容 <面向对象程序设计(java)> https://www.cnblogs.com/ ...
- LG2272/BZOJ1093 「ZJOI2007」最大半连通子图 Tarjan缩点+DAG求最长链
问题描述 LG2272 BZOJ1093 题解 观察半联通的定义,发现图中的一些结点,构成的链一定是一个半联通子图. 此时存在的环可能会干扰求解,于是\(\mathrm{Tarjan}\)缩点. 于是 ...
- 使用Python获取图片的物理尺寸(KB)
如何获取图片的物理尺寸,而非(width, height)? #! -*- coding: utf-8 -*- import requests import io url = "https: ...