【题解】Luogu P5471 [NOI2019]弹跳
先考虑部分分做法:
subtask1:
暴力\(O(nm)\)枚举,跑最短路
subtask2:
吧一行的点压到vector中并排序,二分查找每一个弹跳装置珂以到达的城市,跑最短路
subtask3:
看见是一个链,自然而然的可以想到线段树优化建图,跑最短路
100pts
上面是72pts的暴力做法,其中subtask3的做法给了我们了一些提示,这题要用数据结构优化建图:
在横轴上开一颗线段树,线段树每个节点上是一个存pair的set,存的是\([l,r]\)区间内有第\(id\)个点(\(px[id] \in [l,r]\)),这个点的纵坐标是\(py[id]\)(pair要把纵坐标放前面)
类似线段树优化建图,我们要创建一些虚拟节点:对于第\(i\)个弹跳装置,我们创建一个编号为\(i+n\)的虚拟点,且到虚拟点的距离为所用时间\(T[i]\)
我们从\(1\)号点跑最短路。假如现在对顶是\(x\)号节点,当\(x \leq n\)时,我们更新起点为\(x\)的弹跳装置的虚拟点的dis,并扔进堆;否则就在线段树上先找到\([L[x-n],R[x-n]]\)这个区间(\(x-n\)就是该虚拟点所对应弹跳装置的编号),在这个区间所含的线段树节点上二分出\(D[x-n] \leq py[id] \leq U[x-n]\)中的节点,尝试更新dis,如果成功加入队列,不管成不成功,都从set中删除(根据dij的特性)。
这样最后输出dis[2~n]就行了
这个算法的复杂度是\(O((n+m)\log(n+m)+n\log^2 n)\),常数略(da)大(dao)一(mei)点(jiu)
(\((n+m)\log(n+m)\)是\(n+m\)个点dij的复杂度,\(n\log^2 n\)是\(n\)个节点,每个拆成\(\log n\)个,在set中insert,lowerbound,erase的复杂度)
#include <bits/stdc++.h>
#define N 70005
#define M 150005
#define getchar nc
using namespace std;
inline char nc(){
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
inline int read()
{
register int x=0,f=1;register char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
return x*f;
}
inline void write(register int x)
{
if(!x)putchar('0');if(x<0)x=-x,putchar('-');
static int sta[20];register int tot=0;
while(x)sta[tot++]=x%10,x/=10;
while(tot)putchar(sta[--tot]+48);
}
int n,m,w,h;
int px[N],py[N];
int P[M],T[M],L[M],R[M],D[M],U[M];
set<pair<int,int> > s[N<<2];
vector<int> nv[N];
struct node{
int dis,pos;
bool operator < (const node &x) const{
return x.dis<dis;
}
};
priority_queue<node> q;
int dis[N+M],vis[N+M];
inline void modify(register int x,register int l,register int r,register int id)
{
s[x].insert(make_pair(py[id],id));
if(l==r)
return;
int mid=l+r>>1;
if(px[id]<=mid)
modify(x<<1,l,mid,id);
else
modify(x<<1|1,mid+1,r,id);
}
inline void change(register int x,register int l,register int r,register int id)
{
if(L[id]<=l&&r<=R[id])
{
set<pair<int,int> >::iterator it;
while(19260817)
{
it=s[x].lower_bound(make_pair(D[id],-1));
if(it==s[x].end()||it->first>U[id])
break;
int to=it->second;
if(dis[to]>dis[id+n])
{
dis[to]=dis[id+n];
q.push((node){dis[to],to});
}
s[x].erase(it);
}
return;
}
int mid=l+r>>1;
if(L[id]<=mid)
change(x<<1,l,mid,id);
if(R[id]>mid)
change(x<<1|1,mid+1,r,id);
}
int main()
{
n=read(),m=read(),w=read(),h=read();
for(register int i=1;i<=n;++i)
{
px[i]=read(),py[i]=read();
if(i!=1)
modify(1,1,w,i);
}
for(register int i=1;i<=m;++i)
{
P[i]=read(),T[i]=read(),L[i]=read(),R[i]=read(),D[i]=read(),U[i]=read();
nv[P[i]].push_back(i+n);
}
for(register int i=1;i<=n;++i)
dis[i]=1926081700,vis[i]=0;
dis[1]=0;
q.push((node){0,1});
while(!q.empty())
{
node tmp=q.top();
q.pop();
int x=tmp.pos;
if(vis[x])
continue;
vis[x]=1;
if(x<=n)
{
for(register int i=0;i<nv[x].size();++i)
{
int y=nv[x][i];
dis[y]=dis[x]+T[y-n];
q.push((node){dis[y],y});
}
}
else
change(1,1,w,x-n);
}
for(register int i=2;i<=n;++i)
write(dis[i]),puts("");
return 0;
}
【题解】Luogu P5471 [NOI2019]弹跳的更多相关文章
- luogu P5471 [NOI2019]弹跳
luogu 因为是一个点向矩形区域连边,所以可以二维数据结构优化连边,但是会MLE.关于维护矩形的数据结构还有\(KD-Tree\),所以考虑\(KDT\)优化连边,空间复杂度\(m\sqrt n\) ...
- 洛谷 P5471 - [NOI2019] 弹跳(二维线段树优化建图+堆优化存边)
题面传送门 一道非常有意思的题(大概可以这么形容?) 首先看到这类一个点想一个区域内连边的题目可以很自然地想到线段树优化建图,只不过这道题是二维的,因此需要使用二维线段树优化建图,具体来说,我们外层开 ...
- 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 ...
- [题解] Luogu P5446 [THUPC2018]绿绿和串串
[题解] Luogu P5446 [THUPC2018]绿绿和串串 ·题目大意 定义一个翻转操作\(f(S_n)\),表示对于一个字符串\(S_n\), 有\(f(S)= \{S_1,S_2,..., ...
- 【题解】Luogu P5470 [NOI2019]序列
原题传送门 同步赛上我一开始想了个看似正确却漏洞百出的贪心:按\(a_i+b_i\)的和从大向小贪心 随便想想发现是假的,然后就写了个28pts的暴力dp 杜神后半程说这题就是个贪心,但我没时间写了 ...
- 【题解】Luogu P5468 [NOI2019]回家路线
原题传送门 前置芝士:斜率优化 不会的可以去杜神博客学 这道题我考场上只会拆点跑最短路的70pts做法 后来回家后发现错误的爆搜都能拿满分(刀片) 还有很多人\(O(mt)\)过的,还是要坚持写正解好 ...
- 题解 [NOI2019]弹跳
题目传送门 题目大意 给出 \(n\) 做城市,每座城市都有横纵坐标 \(x,y\).现在给出 \(m\) 个限制 \(p,t,l,r,d,u\),表示从 \(p\) 城市出发,可以花费 \(t\) ...
- [NOI2019] 弹跳
题意: 给你平面上的$n$个点,共有$m$个弹跳装置. 每个弹跳装置可以从点$p_{i}$以$t_{i}$的代价跳到矩形$(L_{i},D_{i}),(R_{i},U_{i})$中的任何一个点. 现在 ...
随机推荐
- rpm安装包制作
RPM是RPM Package Manager(RPM软件包管理器) 1. 安装制作工具 # yum install rpm-build 2. 目录结构 /root/rpmbuild/SOURCES ...
- Android 培训准备资料之project与module的区别(1)
project和module的区别? 现在我们来看看在Android studio中怎样新建一个project (1)file->new->new project. Application ...
- unity点击按钮弹出操作提示界面
1.首先在相应的位置添加一个(UGUI控件)image,在image下添加文本框和按钮设计弹出框内容如图: 2.新建C#脚本UITips using System.Collections; using ...
- RMAN笔记
Rman常用命令 Preview选项 1) 显示用于还原system表空间数据文件的备份文件 RMAN> restore datafile 2 preview; 2) 显示用于还原特 ...
- mysql日期存储格式int,timestarmp,datetime
int (1).4个字节存储,INT的长度是4个字节,存储空间上比datatime少,int索引存储空间也相对较小,排序和查询效率相对较高一点点 (2)可读性极差,无法直观的看到数据. TIMESTA ...
- java.util.ConcurrentModificationException异常;java.util.ConcurrentModificationException实战
写代码遇到这个问题,很多博客文章都是在反复的强调理论,而没有对应的实例,所以这里从实例出发,后研究理论: 一.错误产生情况 1 .字符型 (1)添加 public static void main(S ...
- MyISAM引擎mysql5.6中大型网站数据库优化配置方案
硬件服务器:Dell R710,双至强E5620 CPU.16G内存.6*500G硬盘 操作系统:CentOS5.5 X86_64 系统 Mysql版本:MySQL 5.6 适用于:日IP ...
- Pandas | 21 日期功能
日期功能扩展了时间序列,在财务数据分析中起主要作用.在处理日期数据的同时,我们经常会遇到以下情况 - 生成日期序列 将日期序列转换为不同的频率 创建一个日期范围 通过指定周期和频率,使用date.ra ...
- 洛谷 P1234 小A的口头禅
这里是传送门啊 I'm here! 题目描述 小A最近有了一个口头禅"呵呵",于是他给出了一个矩形,让你求出里面有几个hehe(方向无所谓). 输入输出格式 输入格式: 第一行两个 ...
- limits.conf文件修改注意事项,限制文件描述符数和进程数
参考文章: https://blog.csdn.net/fanren224/article/details/79971359 https://www.cnblogs.com/micmouse521/p ...