题目传送门:LOJ #3159

题意简述:

二维平面上有 \(n\) 个整点,给定每个整点的坐标 \((x_i,y_i)\)。

有 \(m\) 种边,第 \(i\) 种边从 \(p_i\) 号点连向满足 \(l_i\le x_j\le r_i\) 和 \(d_i\le y_j\le u_i\) 的点 \(j\),即一个矩形范围内的所有点。

求 \(1\) 号点到其它每个点的最短路长度。

题解:

考虑 Dijkstra 算法求最短路的过程:

一开始只有起点的距离为 \(0\),而其它点距离为无限大。

每次取出一个距离最短的没被更新过的点,用它更新它能到达的所有未被更新过的点的距离,并将其标记为已被更新。

重复这个过程直到所有点均被更新。

上述过程一般使用单调队列来维护距离最短的点。

而在此题中,一次更新时可能加入的点会有很多很多,不能每次将其一并加入。

可以考虑加入一条边而非点,加入的这条边就代表了这条边连向的所有点的距离。

类似地,每次取出距离最短的边,此时这条边代表的矩形内部的所有点均可以进行更新,因为只会去更新未被更新过的点,所以更新完这些点的距离后,可以把这些点全部删除。

上述方法是最短路中包含“一对多”,“多对多”的边时的处理办法。还有一种方法是使用数据结构模型优化建边,但是一般不会比这种方法来得优。

至于具体如何维护矩形删点操作,删点时可以暴力一个个删除,因为每个点只会被删除一次,问题在于如何快速找到要删除的点。

这里我使用线段树套平衡树(std::set)维护,外层线段树处理横坐标上的区间,内层平衡树可以快速访问目标点将其删除。

下面是代码,时间复杂度为 \(\mathcal{O}(n\log^2n+m\log m)\):

  1. #include <cstdio>
  2. #include <algorithm>
  3. #include <vector>
  4. #include <queue>
  5. #include <set>
  6. #define mp std::make_pair
  7. typedef std::pair<int, int> pii;
  8. typedef std::multiset<pii>::iterator iter;
  9. const int MN = 70005, MM = 150005;
  10. const int MS = 1 << 18 | 7;
  11. int N, M, W, H, yp[MN], vis[MN], dis[MN];
  12. int h[MN], nxt[MM], et[MM], eL[MM], eR[MM], eD[MM], eU[MM];
  13. std::multiset<pii> st[MS];
  14. std::priority_queue<pii> pq;
  15. void Ins(int i, int l, int r, int x, int id) {
  16. st[i].insert(mp(yp[id], id));
  17. if (l == r) return ;
  18. int mid = (l + r) >> 1;
  19. if (x <= mid) Ins(i << 1, l, mid, x, id);
  20. else Ins(i << 1 | 1, mid + 1, r, x, id);
  21. }
  22. void Del(int i, int l, int r, int id, int d) {
  23. if (r < eL[id] || eR[id] < l) return ;
  24. if (eL[id] <= l && r <= eR[id]) {
  25. iter it = st[i].lower_bound(mp(eD[id], 0)), tmp;
  26. while (it != st[i].end() && it -> first <= eU[id]) {
  27. int u = it -> second;
  28. if (!vis[u]) {
  29. vis[u] = 1, dis[u] = d;
  30. for (int j = h[u]; j; j = nxt[j])
  31. pq.push(mp(-d - et[j], j));
  32. }
  33. tmp = it, ++it, st[i].erase(tmp);
  34. }
  35. return ;
  36. }
  37. int mid = (l + r) >> 1;
  38. Del(i << 1, l, mid, id, d);
  39. Del(i << 1 | 1, mid + 1, r, id, d);
  40. }
  41. int main() {
  42. freopen("jump.in", "r", stdin);
  43. freopen("jump.out", "w", stdout);
  44. scanf("%d%d%d%d", &N, &M, &W, &H);
  45. for (int i = 1, x; i <= N; ++i) {
  46. scanf("%d%d", &x, &yp[i]);
  47. Ins(1, 1, W, x, i);
  48. }
  49. for (int i = 1, p; i <= M; ++i) {
  50. scanf("%d%d%d%d%d%d", &p, &et[i], &eL[i], &eR[i], &eD[i], &eU[i]);
  51. nxt[i] = h[p], h[p] = i;
  52. }
  53. dis[1] = 0, vis[1] = 1;
  54. for (int i = h[1]; i; i = nxt[i])
  55. pq.push(mp(-et[i], i));
  56. while (!pq.empty()) {
  57. pii ed = pq.top(); pq.pop();
  58. int dis = -ed.first, id = ed.second;
  59. Del(1, 1, W, id, dis);
  60. }
  61. for (int i = 2; i <= N; ++i) printf("%d\n", dis[i]);
  62. return 0;
  63. }

LOJ 3159: 「NOI2019」弹跳的更多相关文章

  1. LOJ 3158: 「NOI2019」序列

    题目传送门:LOJ #3158. 题意简述: 给定两个长度为 \(n\) 的正整数序列 \(a,b\),要求在每个序列中都选中 \(K\) 个下标,并且要保证同时在两个序列中都被选中的下标至少有 \( ...

  2. LOJ 3160: 「NOI2019」斗主地

    题目传送门:LOJ #3160. 简要题意: 有一个长度为 \(n\) 的序列 \(a\),初始时 \(a_i=i\) 或 \(a_i=i^2\),这取决于 \(\mathrm{type}\) 的值. ...

  3. LOJ 3156: 「NOI2019」回家路线

    题目传送门:LOJ #3156. 题意简述: 有一张 \(n\) 个点 \(m\) 条边的有向图,边有两个权值 \(p_i\) 和 \(q_i\)(\(p_i<q_i\))表示若 \(p_i\) ...

  4. 「NOI2019」弹跳(KD树)

    题意:w×h网格中有n个点,m条边.每条边可以从p点花费t时间到一个矩形中的任意点,求1号点到每个点的最少时间. \(1<=w,h<=n<=70000,1<=m<=150 ...

  5. @loj - 3157@「NOI2019」机器人

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 小 R 喜欢研究机器人. 最近,小 R 新研制出了两种机器人,分 ...

  6. loj3161「NOI2019」I 君的探险(随机化,整体二分)

    loj3161「NOI2019」I 君的探险(随机化,整体二分) loj Luogu 题解时间 对于 $ N \le 500 $ 的点,毫无疑问可以直接 $ O(n^2) $ 暴力询问解决. 考虑看起 ...

  7. Loj #2192. 「SHOI2014」概率充电器

    Loj #2192. 「SHOI2014」概率充电器 题目描述 著名的电子产品品牌 SHOI 刚刚发布了引领世界潮流的下一代电子产品--概率充电器: 「采用全新纳米级加工技术,实现元件与导线能否通电完 ...

  8. Loj #3096. 「SNOI2019」数论

    Loj #3096. 「SNOI2019」数论 题目描述 给出正整数 \(P, Q, T\),大小为 \(n\) 的整数集 \(A\) 和大小为 \(m\) 的整数集 \(B\),请你求出: \[ \ ...

  9. Loj #3093. 「BJOI2019」光线

    Loj #3093. 「BJOI2019」光线 题目描述 当一束光打到一层玻璃上时,有一定比例的光会穿过这层玻璃,一定比例的光会被反射回去,剩下的光被玻璃吸收. 设对于任意 \(x\),有 \(x\t ...

随机推荐

  1. thinkphp5.1 - twig使用

    thinkphp5.1 - twig使用1.安装按照:https://github.com/yunwuxin/think-twigTwig Template For ThinkPHP5 安装 comp ...

  2. django实战(五)--增加数据

    urls.py urlpatterns=[ path('curd/add/',views.curd_add,name='curdadd'), path('curd/saveadd/',views.cu ...

  3. PostMan测试REST接口时候,如何绕过登录的验证

    原文地址:https://blog.csdn.net/qq_34178998/article/details/80361315 之前测试的时候,需要页面进行登录之后,才能让访问后台程序,但是在进行接口 ...

  4. select2的简单使用

    静态下拉列表 修改 type_template.html  引入JS <!-- slect2插件--> <link rel="stylesheet" href=& ...

  5. iOS组件化实现方案

    作者原文iOS组件化 - 路由架构从0到1实战  合伙呀 1.CTMediator作为路由中间件 2.基础UI组件以pod形式引入,并且能够独立运行调试 3.基础工具组件以pod形式引入,并且能够独立 ...

  6. 中文情感分析——snownlp类库 源码注释及使用

    最近发现了snownlp这个库,这个类库是专门针对中文文本进行文本挖掘的. 主要功能: 中文分词(Character-Based Generative Model) 词性标注(TnT 3-gram 隐 ...

  7. [转帖]【译】RAID的概念和RAID对于SQL性能的影响

    [译]RAID的概念和RAID对于SQL性能的影响 https://www.cnblogs.com/VicLiu/p/11479427.html 简介 我们都听说过RAID,也经常作为SQL DBA. ...

  8. pod的yaml说明

    apiVersion: v1 #指定api版本,此值必须在kubectl apiversion中 kind: Pod #指定创建资源的角色/类型 metadata: #资源的元数据/属性 name: ...

  9. 【HTML】前台input上传限制文件类型

    仅限制xls文件上传 <input id="uploadSkufile" type="file" value="批量导入" style ...

  10. MD5加密方法HashPasswordForStoringInConfigFile(string,string)过时问题处理方法

    最近写代码的时候一直有一种很奇怪的感觉,查了一下发现原来是系统中的MD5加密方法报了过时的警告,虽然对系统没有任何影响,但是开发过程中绿色波浪线就像挥之不去的阴影一样.开发人员多多少少都会有点强迫症, ...