题意:一个w×hw\times hw×h的二维平面上有nnn个城市,有mmm个弹跳装置,第iii个可以花费tit_iti​的时间从城市pip_ipi​跳到矩形x∈[l,r],y∈[u,d]x\in [l,r],y\in[u,d]x∈[l,r],y∈[u,d]中的任意一个城市。求从111到其他每个城市的最小时间。

w,h≤n≤7×104,m≤1.5×105w,h\leq n\leq7\times 10^4,m\leq1.5\times10^5w,h≤n≤7×104,m≤1.5×105 空间限制128M

考虑直接套dijkstra的思路,每次选出dis最小的点,松弛它可以到的点,然后把它删掉。

挪到二维平面上,你需要支持:

  1. 全局询问最小值
  2. 矩形取min⁡\minmin
  3. 删除一个点

用kdt或者二维线段树维护即可。这里用的是二维线段树。

需要注意的细节:

  1. 要动态开点
  2. 要用pair记录最小值的编号,且初值是(INF,INF),否则可能打了个lazy标记之后first是答案标号却是0。
  3. 大常数选手需要维护一个最大值剪枝。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cctype>
#include <vector>
#include <utility>
#define re register
#define MAXN 70005
using namespace std;
const int INF=0x7fffffff;
inline int read()
{int ans=0;char c=getchar();while (!isdigit(c)) c=getchar();while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();return ans;
}
typedef pair<int,int> pi;
#define mp make_pair
#define fi first
#define se second
struct tran{int xl,xr,yl,yr;tran(int xl=0,int xr=0,int yl=0,int yr=0):xl(xl),xr(xr),yl(yl),yr(yr){}};
inline bool belong(const tran& b,const tran& a){return a.xl<=b.xl&&b.xr<=a.xr&&a.yl<=b.yl&&b.yr<=a.yr;}
inline bool ninter(const tran& a,const tran& b){return (a.xr<b.xl||b.xr<a.xl)||(a.yr<b.yl||b.yr<a.yl);}
struct edge{tran t;int w;};
vector<edge> e[MAXN];
#define ch(x) t[p].son[x]
int tot=0,rt;
struct node{tran pos;pi mn;int mx,sum,lzy,son[4];}t[MAXN<<5];
inline int newnode(int xl,int xr,int yl,int yr)
{int p=++tot;t[p].pos=tran(xl,xr,yl,yr);t[p].mn=mp(INF,INF);t[p].mx=0;t[p].lzy=INF;return p;
}
inline void update(int p)
{t[p].sum=t[ch(0)].sum+t[ch(1)].sum+t[ch(2)].sum+t[ch(3)].sum;t[p].mn=mp(INF,INF),t[p].mx=0;for (re int i=0;i<4;++i) if (ch(i)) t[p].mn=min(t[p].mn,t[ch(i)].mn),t[p].mx=max(t[p].mx,t[ch(i)].mx);
}
inline void pushlzy(int p,int v)
{if (t[p].sum==0) return;t[p].mn.fi=min(t[p].mn.fi,v),t[p].mx=min(t[p].mx,v),t[p].lzy=min(t[p].lzy,v);
}
inline void pushdown(int p)
{if (t[p].lzy<INF){for (re int i=0;i<4;++i) pushlzy(ch(i),t[p].lzy);t[p].lzy=INF;}
}
void modify(int& p,int xl,int xr,int yl,int yr,int x,int y,int v)
{if (!p) p=newnode(xl,xr,yl,yr);if (!belong(tran(x,x,y,y),t[p].pos)) return;pushdown(p);if (t[p].pos.xl==t[p].pos.xr&&t[p].pos.yl==t[p].pos.yr) return (void)(t[p].sum=(v<INF),t[p].mn=mp(INF,v),t[p].mx=(v==INF? 0:INF));int xmid=(xl+xr)>>1,ymid=(yl+yr)>>1; modify(ch(0),xl,xmid,yl,ymid,x,y,v);modify(ch(1),xl,xmid,ymid+1,yr,x,y,v);modify(ch(2),xmid+1,xr,yl,ymid,x,y,v);modify(ch(3),xmid+1,xr,ymid+1,yr,x,y,v);        update(p);
}
void modify(int p,tran q,int v)
{if (!p) return;pushdown(p);    if (t[p].mx<=v) return;if (belong(t[p].pos,q)) return pushlzy(p,v);if (ninter(t[p].pos,q)) return;for (int i=0;i<4;i++) modify(ch(i),q,v);update(p);
}
int x[MAXN],y[MAXN],ans[MAXN];
int main()
{int n,m,w,h;n=read(),m=read(),w=read(),h=read();for (int i=1;i<=n;i++){x[i]=read(),y[i]=read();modify(rt,1,w,1,h,x[i],y[i],i);}for (int i=1;i<=m;i++){int p,t,l,r,d,u;p=read(),t=read(),l=read(),r=read(),d=read(),u=read();e[p].push_back((edge){tran(l,r,d,u),t});}modify(1,tran(x[1],x[1],y[1],y[1]),0);for (int T=1;T<=n;T++){pi tmp=t[1].mn;int u=tmp.se,dis=tmp.fi;ans[u]=dis;for (int i=0;i<(int)e[u].size();i++)modify(1,e[u][i].t,dis+e[u][i].w);modify(rt,1,w,1,h,x[u],y[u],INF);}for (int i=2;i<=n;i++) printf("%d\n",ans[i]);return 0;
}

【NOI2019】弹跳【二维线段树】【dijkstra】相关推荐

  1. 10.25T2 二维线段树

    Description 为了准备校庆庆典,学校招募了一些学生组成了一个方阵,准备在庆典上演出. 这个方阵是一个n*m的矩形,第i行第j列有一名学生,他有一个能力值Ai,j. 校长会定期检查一个p*q的 ...

  2. BZOJ2877 NOI2012魔幻棋盘(二维线段树)

    显然一个序列的gcd=gcd(其差分序列的gcd,序列中第一个数).于是一维情况直接线段树维护差分序列即可. 容易想到将该做法拓展到二维.于是考虑维护二维差分,查询时对差分矩阵求矩形的gcd,再对矩形 ...

  3. POJ2155二维线段树

    题意:      给一个n*n的01矩阵,然后有两种操作(m次)C x1 y1 x2 y2是把这个小矩形内所有数字异或一遍,Q x y 是询问当前这个点的值是多少?n<=1000 m<=5 ...

  4. poj1195 Mobile phones 二维线段树入门

    二维线段树就是树套树,线段树套线段树... #include<iostream> #include<cstdio> #include<cstring> #inclu ...

  5. POJ-2155 Matrix 二维线段树 | 树状数组

    题目链接:http://poj.org/problem?id=2155 比较典型的二维线段树题目,直接永久更新即可,在询问的时候,要询问每个x区间的子树,复杂度O(log(n)^2). 也可以用树状数 ...

  6. [POJ2155] Matrix(二维线段树,树套树)

    题目链接:http://poj.org/problem?id=2155 题意:给一个01矩阵,两个操作,翻转:子矩阵里每一个数都由0变1,1变0. 查询:查询某一点是0还是1. 一直以为二维线段树就是 ...

  7. HDU1823(二维线段树)

    题目:Luck and Love 题意:当操作符为'I'时,表示有一个MM报名,后面接着一个整数,H表示身高,两个浮点数,A表示活泼度,L表示缘分值. (100<=H<=200, 0.0& ...

  8. 模板:二维线段树(线段树套线段树)

    文章目录 问题 解析 单点修改 询问 完整代码 标记永久化 代码 所谓二维线段树,就是有两个维度的线段树 (逃) 问题 给出一个矩形 要求支持以下操作: 1.询问一个子矩形的最值 2.修改某一个单点的 ...

  9. BZOJ.4553.[HEOI2016TJOI2016]序列(DP 树状数组套线段树/二维线段树(MLE) 动态开点)

    题目链接:BZOJ 洛谷 \(O(n^2)\)DP很好写,对于当前的i从之前满足条件的j中选一个最大值,\(dp[i]=d[j]+1\) for(int j=1; j<i; ++j)if(a[j ...

最新文章

  1. LTE: MIB和SIB,小区选择和重选规则
  2. 2018-2019-1 20165310 20165315 20165226 实验一 开发环境的熟悉
  3. 在windows上的git bash中安装tree 和 linux tree命令使用
  4. Luogu P1886 滑动窗口
  5. 专访黄勇:Java在未来的很长一段时间仍是主流
  6. Mysql数据唯一约束与唯一索引案例总结及踩坑记(含NULL值与唯一约束唯一索引的搭配使用)
  7. 利用Apache POI读取并解析Excel的数据
  8. 【渝粤教育】国家开放大学2018年春季 0176-22T电机学(一) 参考试题
  9. 8次c语言上机作业答案,计算机二级C语言上机题库及答案2017
  10. 机器视觉技术及应用_工业机器人视觉技术的应用前景
  11. linux下golang编译环境搭建
  12. Mybatis框架相关知识讲解
  13. 解放双手,基于github travis-ci docker自动化部署java项目
  14. spark sql练习之join操作
  15. c盘java文件误删_C盘的文件被误删如何恢复
  16. vue项目pc端和移动端适配
  17. Python深度学习之LSTM文本生成
  18. 再见了, 达叔!我用Python回顾一代喜剧大师203部作品,太经典了!
  19. Unity3D游戏开发介绍
  20. 什么是索引覆盖?什么是索引下推?

热门文章

  1. r vector 4 elements_Vector类与Enumeration接口
  2. sql limit不接具体数字_这21个写SQL的好习惯,你要养成呀
  3. 那些年,画家发明的黑科技
  4. 一壶 100℃ 的开水从多高倒进嘴里不会觉得烫?
  5. 大道至简,大数据的小窍门
  6. 风靡全球的人工智能,如何赶上这班车?
  7. 《SAS编程与数据挖掘商业案例》学习笔记之十四
  8. 计算机广告制作未来发展还行吗,计算机多媒体设计专业和广告设计制作那个好...
  9. oracle中prad函数_024 SQL函数
  10. 浅谈Redis五种数据结构的底层原理