[BZOJ1171][BZOJ2892]大sz的游戏

试题描述

大sz最近在玩一个由星球大战改编的游戏。话说绝地武士当前共控制了N个星球。但是,西斯正在暗处悄悄地准备他们的复仇计划。绝地评议会也感觉到了这件事。于是,准备加派绝地武士到各星球防止西斯的突袭。一个星球受到攻击以后,会尽快通知到总基地。需要的时间越长的星球就需要越多绝地武士来防御。为了合理分配有限的武士,大sz需要你帮他求出每个星球各需要多少时间能够通知到总基地。由于某种原因,N个星球排成一条直线,编号1至N。其中总基地建在1号星球上。每个星球虽然都是绝地武士控制的,但是上面居住的生物不一定相同,并且科技水平也不一样。第i个星球能收到并分析波长在[xi, yi]之间的信号,并且也能够发出在这个区间的信号,但是不能发出其他任何波长的信号。由于技术原因,每个星球只能发信号到比自己编号小的距离不超过L的星球。特别地,强大的总基地可以接收任何波长的信号。每个星球处理接收到的数据需要1个单位时间,传输时间可以忽略不计。

输入

第一行两个正整数N、L。接下来N-1行,总共第i行包含了三个正整数xi、yi、li,其中li表示第i个星球距离1号星球li,满足li严格递增。

输出

总共N-1行,每行一个数分别表示2到N号星球至少需要多少单位时间,总基地能够处理好数据,如果无法传到总基地则输出-1。

输入示例1

  1.  

输出示例1

  1.  

输入示例2

  1.  

输出示例2

  1.  

数据规模及约定

30%的数据满足N <=20000;
100%的数据满足2 <=N<= 2.5*10^5、0<=xi,yi,li<=2*10^9,1<=L<=2*10^9,xi<=yi.

题解

首先这是一道裸 dp,f(i)表示对于星球 i 要求的答案,f(i) = min{ f(j) | [xi, yi]与[xj, yj]有交集 & l[i] - l[j] <= L & 0 < j < i } + 1.

最棘手的是两个区间有没有交集的问题。可以考虑离散后用线段树,但是要资瓷区间加入、删除、查询操作,不好搞,注意在上面的转移方程中,随着 i 的增长,j 所在的区间是一直向右移动的(因为 l[i] - l[j] <= L),或者说是一个滑动窗口,可以再套一个单调队列。

此外这里的线段树标记不好合并,所以干脆不进行标记下传;只在线段树的节点刚好被操作区间完全包含时,在这个节点上打标记,再向上更新一下最小值即可,询问时需要把节点到根的标记都取一个 min。(注意为什么这里我要把“标记”标红)

  1. #include <iostream>
  2. #include <cstring>
  3. #include <cstdio>
  4. #include <algorithm>
  5. #include <queue>
  6. #include <list>
  7. using namespace std;
  8.  
  9. const int BufferSize = 1 << 16;
  10. char buffer[BufferSize], *Head, *tail;
  11. inline char Getchar() {
  12. if(Head == tail) {
  13. int l = fread(buffer, 1, BufferSize, stdin);
  14. tail = (Head = buffer) + l;
  15. }
  16. return *Head++;
  17. }
  18. int read() {
  19. int x = 0, f = 1; char c = Getchar();
  20. while(!isdigit(c)){ if(c == '-') f = -1; c = Getchar(); }
  21. while(isdigit(c)){ x = x * 10 + c - '0'; c = Getchar(); }
  22. return x * f;
  23. }
  24.  
  25. #define maxn 250005
  26. #define oo 2147483646
  27. int n, Len, num[maxn<<1], cnt, x[maxn], y[maxn], l[maxn], f[maxn], que[maxn], hd, tl;
  28.  
  29. list <int> Q[maxn<<3];
  30. int res[maxn<<3];
  31. void update(int L, int R, int o, int ql, int qr, int p, bool tp) {
  32. int M = L + R >> 1, lc = o << 1, rc = lc | 1;
  33. if(ql <= L && R <= qr) {
  34. if(!tp) {
  35. while(!Q[o].empty() && Q[o].front() <= p) Q[o].pop_front();
  36. }
  37. else {
  38. while(!Q[o].empty() && f[Q[o].back()] >= f[p]) Q[o].pop_back();
  39. Q[o].push_back(p);
  40. }
  41. res[o] = oo;
  42. if(!Q[o].empty()) {
  43. if(L < R) res[o] = min(res[lc], res[rc]);
  44. res[o] = min(res[o], f[Q[o].front()]);
  45. }
  46. else if(L < R) res[o] = min(res[lc], res[rc]);
  47. return ;
  48. }
  49. if(ql <= M) update(L, M, lc, ql, qr, p, tp);
  50. if(qr > M) update(M+1, R, rc, ql, qr, p, tp);
  51. res[o] = min(res[lc], res[rc]);
  52. if(!Q[o].empty()) res[o] = min(res[o], f[Q[o].front()]);
  53. return ;
  54. }
  55. int query(int L, int R, int o, int ql, int qr) {
  56. if(ql <= L && R <= qr) return res[o];
  57. int M = L + R >> 1, lc = o << 1, rc = lc | 1, ans = oo;
  58. if(ql <= M) ans = min(ans, query(L, M, lc, ql, qr));
  59. if(qr > M) ans = min(ans, query(M+1, R, rc, ql, qr));
  60. if(!Q[o].empty()) ans = min(ans, f[Q[o].front()]);
  61. return ans;
  62. }
  63.  
  64. int main() {
  65. n = read(); Len = read();
  66. for(int i = 2; i <= n; i++) {
  67. num[++cnt] = x[i] = read(); num[++cnt] = y[i] = read();
  68. l[i] = read();
  69. }
  70. sort(num + 1, num + cnt + 1);
  71. for(int i = 2; i <= n; i++) {
  72. x[i] = lower_bound(num + 1, num + cnt + 1, x[i]) - num;
  73. y[i] = lower_bound(num + 1, num + cnt + 1, y[i]) - num;
  74. }
  75.  
  76. for(int i = 0; i < (maxn<<3); i++) res[i] = oo;
  77. que[++tl] = 1;
  78. f[1] = 0; x[1] = 1; y[1] = cnt; l[1] = 0;
  79. update(1, cnt, 1, 1, cnt, 1, 1);
  80. for(int i = 2; i <= n; i++) {
  81. while(hd < tl && l[que[hd+1]] < l[i] - Len) {
  82. hd++;
  83. update(1, cnt, 1, x[que[hd]], y[que[hd]], que[hd], 0);
  84. }
  85. f[i] = query(1, cnt, 1, x[i], y[i]) + 1;
  86. if(f[i] < oo) {
  87. printf("%d\n", f[i]);
  88. que[++tl] = i;
  89. update(1, cnt, 1, x[i], y[i], i, 1);
  90. }
  91. else puts("-1");
  92. }
  93.  
  94. return 0;
  95. }
  96. /*
  97. 3 3
  98. 1 2 1
  99. 2 3 2
  100.  
  101. 8 100000
  102. 2 8192813 100000
  103. 5 23131346 113213
  104. 23131346 83131346 123213
  105. 23131346 83131346 199213
  106. 231346 103131346 213213
  107. 213 1038 213214
  108. 854 5432153 214214
  109. */

[BZOJ1171][BZOJ2892]大sz的游戏的更多相关文章

  1. 【BZOJ1171】大sz的游戏(线段树+单调队列)

    点此看题面 大致题意: 有\(n\)个点,两点间最大通讯距离为\(L\).已知除\(1\)号点外第\(i\)个点能够发出和接收的信号区间\([l_i,r_i]\)以及到\(1\)号点的距离\(dis_ ...

  2. 【BZOJ-2892&1171】强袭作战&大sz的游戏 权值线段树+单调队列+标记永久化+DP

    2892: 强袭作战 Time Limit: 50 Sec  Memory Limit: 512 MBSubmit: 45  Solved: 30[Submit][Status][Discuss] D ...

  3. bzoj 1171 大sz的游戏& 2892 强袭作战 (线段树+单调队列+永久性flag)

    大sz的游戏 Time Limit: 50 Sec  Memory Limit: 357 MBSubmit: 536  Solved: 143[Submit][Status][Discuss] Des ...

  4. BZOJ1171: 大sz的游戏&BZOJ2892: 强袭作战

    Description 大sz最近在玩一个由星球大战改编的游戏.话说绝地武士当前共控制了N个星球.但是,西斯正在暗处悄悄地准备他们的复仇计划.绝地评议会也感觉到了这件事.于是,准备加派绝地武士到各星球 ...

  5. BZOJ1171 : 大sz的游戏

    f[i]=min(f[j])+1,线段j与线段i有交,且l[i]-l[j]<=L. 线段j与线段i有交等价于y[j]>=x[i],x[j]<=y[i]. 因为l[i]递增,所以可以维 ...

  6. BZOJ 1171: 大sz的游戏

    ZJOI讲课的题目,数据结构什么的还是很友好的说 首先我们发现题目中提到的距离\(\le L\)的东西显然可以用单调队列维护 但是暴力搞去不掉区间并的限制,那么我们考虑从区间并入手 对于这种问题的套路 ...

  7. 刺猬大作战(游戏引擎用Free Pascal写成,GUI用C++写成,使用SDL和Qt4)

    游戏特性[编辑] 游戏引擎用Free Pascal写成,GUI用C++写成,使用SDL和Qt4[2]. 0.9.12开始支持实时动态缩放游戏画面. 个性化[编辑] 刺猬大作战有着高度定制性 游戏模式: ...

  8. [知了堂学习笔记]_用JS制作《飞机大作战》游戏_第2讲(四大界面之间的跳转与玩家飞机的移动)

    一.通过点击按钮事件,实现四大界面之间的跳转: (一)跳转的思路: 1.打开软件,只显示登录界面(隐藏游戏界面.暂停界面.玩家死亡界面) 2.点击微信登录(QQ登录)跳转到游戏界面,隐藏登录界面 3. ...

  9. [知了堂学习笔记]_用JS制作《飞机大作战》游戏_第4讲(创建敌方飞机、敌方飞机发射子弹、玩家子弹击中敌方小飞机,小飞机死亡)

    一.创建敌方飞机 1.思考创建思路: 创建敌方飞机思路与创建玩家飞机思路一样: (1)思考敌方飞机具备什么属性: 敌方飞机的图片.坐标.飞行速度.状态(是否被击中) 设置小飞机被击中时消失时间.飞机可 ...

随机推荐

  1. 支持Json进行操作的Javascript类库TAFFY DB

    前段时间工作中用到Json数据,希望将一些简单的增删改查放到客户端来做,这样也能减少服务器端的压力.分别查找了几个可以对Json进行操作的javascript 类库,最终选定了TAFFY DB.原因如 ...

  2. [BZOJ2879][Noi2012]美食节(最小费用最大流动态加边)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2879 分析: 和bzoj1070一样,但这题的数据范围大了很多,如果直接建图就会TLE ...

  3. 第十章:Javascript子集和扩展

    本章讨论javascript的集和超集,其中子集的定义大部分处于安全考虑.只有使用这门语言的一个安全的子集编写脚本,才能让代码执行的更安全.更稳定.ECMScript3标准是1999年版本的,10年后 ...

  4. 每天一个linux命令(44):ifconfig命令

    许多windows非常熟悉ipconfig命令行工具,它被用来获取网络接口配置信息并对此进行修改.Linux系统拥有一个类似的工具,也就是ifconfig(interfaces config).通常需 ...

  5. websocket在.net4.5中实现的简单demo

    以下代码环境要求:win8或win10, .net4.5+IIS8 win7上是IIS7,win7上.net本身不直接支持websocket, win7可以用superwebsocket, 或自己根据 ...

  6. “耐撕”团队2016.04.14站立会议

    1. 时间 : 19:20--19:40  共计20分钟 2. 人员 : Z   郑蕊 * 组长 (博客:http://www.cnblogs.com/zhengrui0452/), P 濮成林(博客 ...

  7. Error: java.lang.UnsatisfiedLinkError: no ntvinv in java.library.path

    Error Message When compiling or executing a Java application that uses the ArcObjects Java API, the ...

  8. maven初学(二)archeType插件使用

    archeType是一个maven插件,它的主要功能是根据模板来创建工程结构 创建工程结构: 1,创建工程目录 2,输入命令:mvn archetype:generate 3,选择需要的archety ...

  9. hdu1231 最大连续子序列

    #include<stdio.h> #include<string.h> #define maxn 10010 int a[maxn],dp[maxn]; int main() ...

  10. Java基础-重写-子类重写父类中的方法后执行情况

    代码 public class Test { public static void main(String[] args) { Shape shape = new Circle(); System.o ...