小清新线段树题((

每个位置的边只能向靠右的三个方向走,最后要走到一条基准线上。即对于一个点 \((x, y)\),它最后应该落在 \((k, y + |k - x|)\)。

士兵可以一个一个进行移动,所以互相的移动行程不会互相干扰。考虑利用这个性质将题目从二维转换为一维。

即:有一队士兵排好队,每个士兵有一个预选定的位置。当轮到第 \(i\) 位士兵选位置时,若预选定位置有其它士兵,则选择当前选定位置右边紧挨着的位置,直到当前选定位置上不再有其他士兵后站入该位置。试问至少需要新加入多少个格子可以收容所有士兵。

盲目感觉这种“当前放不了就考虑下一个”的题目常常会考虑维护一些后缀,所以接下来我们引入后缀。

如果构造一个数组 \(A\),且初始时 \(\forall A_i = -1 \space \mathrm{s.t.} i \in [1, n]\)。且定义数组 \(f\),表示有 \(f_i\) 个士兵预选定了 \(i\) 这个位置。则答案为序列 \(A + f\) 的后缀和最大值。(建议自己手 Rua 一下。

但对于 \(i > n\) 的部分,这样是不好处理的。因为在原题中,这些位置也应该参与到“新加入位置”的贡献中。于是更改 \(A\) 的构造方式。

在 \(i \in [1, n]\) 的部分,我们直接令 \(A_i = -(n - i + 1)\),即直接储存后缀。

而 \(i > n\) 的部分,我们尝试分析其贡献。如果要使用 \(n + 2\) 这个位置,则我们需要先添加一个 \(n + 1\) 的位置,也就是第 \(n + 2\) 项初值应该为 \(1\)。同理可知 \(n + 1 \dots n + n\) 等位置,故也可令 \(i > n\) 的部分中 \(A_i = -(n - i + 1)\)。

不难发现,现在答案为 \(\max \{ A_i + g_i \} \space \mathrm{s.t.} i \in [1, w]\),其中 \(w\) 是预选定位置最靠右的一个,\(g\) 是 \(f\) 的后缀序列。

\(f\) 是动态更新的,每次更新会先区间修改 \(g\),最终作用于 \(A + f\)。故 \(A + g\) 可以直接使用区修区查的线段树维护。\(w\) 使用 set,加一个计数器维护即可。

总时间复杂度 \(O(n \log n)\)。这里使用的是常数较小的 zkw 线段树。

  1. #include <map>
  2. #include <set>
  3. #include <cstdio>
  4. using namespace std;
  5. int Abs (int x) { return x < 0 ? -x : x; }
  6. int Max (int x, int y) { return x > y ? x : y; }
  7. int Min (int x, int y) { return x < y ? x : y; }
  8. int Read () {
  9. int x = 0, k = 1;
  10. char s = getchar ();
  11. while (s < '0' || s > '9') {
  12. if (s == '-')
  13. k = -1;
  14. s = getchar ();
  15. }
  16. while ('0' <= s && s <= '9')
  17. x = (x << 3) + (x << 1) + (s ^ 48), s = getchar ();
  18. return x * k;
  19. }
  20. void Write (int x) {
  21. if (x < 0)
  22. putchar ('-'), x = -x;
  23. if (x > 9)
  24. Write (x / 10);
  25. putchar (x % 10 + '0');
  26. }
  27. void Print (int x, char s) { Write (x), putchar (s); }
  28. const int Inf = 1e9;
  29. const int Maxn = 4e5 + 5;
  30. set <int> s;
  31. map <int, int> Vis[Maxn];
  32. int a[Maxn], Tr[Maxn * 3], Lazy[Maxn * 3], Cnt[Maxn], p;
  33. void Make_Tree (int n) {
  34. p = 1;
  35. while (p < n + 2)
  36. p <<= 1;
  37. Tr[p + n + 1] = Tr[p] = -Inf;
  38. for (int i = 1; i <= n; i++)
  39. Tr[p + i] = a[i];
  40. for (int i = p + n + 1; i > 1; i--)
  41. Tr[i >> 1] = Max (Tr[i], Tr[i ^ 1]);
  42. }
  43. void Update (int l, int r, int x) {
  44. for (l += p - 1, r += p + 1; (l ^ r) != 1; l >>= 1, r >>= 1) {
  45. if (!(l & 1))
  46. Tr[l ^ 1] += x, Lazy[l ^ 1] += x;
  47. if (r & 1)
  48. Tr[r ^ 1] += x, Lazy[r ^ 1] += x;
  49. Tr[l >> 1] = Max (Tr[l], Tr[l ^ 1]) + Lazy[l >> 1];
  50. Tr[r >> 1] = Max (Tr[r], Tr[r ^ 1]) + Lazy[r >> 1];
  51. }
  52. for (; l > 1; l >>= 1)
  53. Tr[l >> 1] = Max (Tr[l], Tr[l ^ 1]) + Lazy[l >> 1];
  54. }
  55. int Query (int l, int r) {
  56. int Res = -Inf, Resl = -Inf, Resr = -Inf;
  57. for (l += p - 1, r += p + 1; (l ^ r) != 1; l >>= 1, r >>= 1) {
  58. if (!(l & 1))
  59. Resl = Max (Resl, Tr[l ^ 1]);
  60. if (r & 1)
  61. Resr = Max (Resr, Tr[r ^ 1]);
  62. Resl += Lazy[l >> 1], Resr += Lazy[r >> 1];
  63. }
  64. Res = Max (Resl, Resr);
  65. for (; l > 1; l >>= 1)
  66. Res += Lazy[l >> 1];
  67. return Res;
  68. }
  69. int main () {
  70. int n = Read (), k = Read (), m = Read ();
  71. for (int i = 1; i <= 2 * n; i++)
  72. a[i] = -(n - i + 1);
  73. Make_Tree (n << 1);
  74. for (int i = 1, x, y; i <= m; i++) {
  75. x = Read (), y = Read ();
  76. if (!Vis[x][y]) {
  77. if (!Cnt[y + Abs (x - k)])
  78. s.insert (y + Abs (x - k));
  79. Cnt[y + Abs (x - k)]++;
  80. Update (1, y + Abs (x - k), 1), Vis[x][y] = true;
  81. }
  82. else {
  83. Cnt[y + Abs (x - k)]--;
  84. if (!Cnt[y + Abs (x - k)])
  85. s.erase (y + Abs (x - k));
  86. Update (1, y + Abs (x - k), -1), Vis[x][y] = false;
  87. }
  88. if (s.empty ())
  89. Print (0, '\n');
  90. else
  91. Print (Max (0, Query (1, *s.rbegin ())), '\n');
  92. }
  93. return 0;
  94. }

Solution -「CF1373G」Pawns的更多相关文章

  1. Solution -「构造」专练

    记录全思路过程和正解分析.全思路过程很 navie,不过很下饭不是嘛.会持续更新的(应该). 「CF1521E」Nastia and a Beautiful Matrix Thought. 要把所有数 ...

  2. Solution -「原创」Destiny

    题目背景 题目背景与题目描述无关.签到愉快. 「冷」 他半靠在床沿,一缕感伤在透亮的眼眸间荡漾. 冷见惆怅而四散逃去.经历嘈杂喧嚣,感官早已麻木.冷又见空洞而乘隙而入.从里向外,这不是感官的范畴. 他 ...

  3. Solution -「GLR-R2」教材运送

    \(\mathcal{Description}\)   Link.   给定一棵包含 \(n\) 个点,有点权和边权的树.设当前位置 \(s\)(初始时 \(s=1\)),每次在 \(n\) 个结点内 ...

  4. Solution -「WF2011」「BZOJ #3963」MachineWorks

    \(\mathcal{Description}\)   Link.   给定你初始拥有的钱数 \(C\) 以及 \(N\) 台机器的属性,第 \(i\) 台有属性 \((d_i,p_i,r_i,g_i ...

  5. Solution -「LOCAL」二进制的世界

    \(\mathcal{Description}\)   OurOJ.   给定序列 \(\{a_n\}\) 和一个二元运算 \(\operatorname{op}\in\{\operatorname{ ...

  6. Solution -「SHOI2016」「洛谷 P4336」黑暗前的幻想乡

    \(\mathcal{Description}\)   link.   有一个 \(n\) 个结点的无向图,给定 \(n-1\) 组边集,求从每组边集选出恰一条边最终构成树的方案树.对 \(10^9+ ...

  7. Solution -「LOCAL」大括号树

    \(\mathcal{Description}\)   OurTeam & OurOJ.   给定一棵 \(n\) 个顶点的树,每个顶点标有字符 ( 或 ).将从 \(u\) 到 \(v\) ...

  8. Solution -「ZJOI2012」「洛谷 P2597」灾难

    \(\mathcal{Description}\)   link.   给定一个捕食网络,对于每个物种,求其灭绝后有多少消费者失去所有食物来源.(一些名词与生物学的定义相同 w.)   原图结点数 \ ...

  9. Solution -「JSOI2008」「洛谷 P4208」最小生成树计数

    \(\mathcal{Description}\)   link.   给定带权简单无向图,求其最小生成树个数.   顶点数 \(n\le10^2\),边数 \(m\le10^3\),相同边权的边数不 ...

随机推荐

  1. insert语句生成的存储过程

    问题: 1.如何配置数据库数据: 方式一:图形界面点击输入数据,导出成sql. 缺点:表多,数据多的时候非常繁琐,字段含义需要另外开窗口对照. 方式二:徒手写或者修改已有语句:insert table ...

  2. apparmor 源码分析

    这里不对apparmor做介绍,记录一下源码分析过程. 初始化 static int __init apparmor_init(void) -> security_add_hooks(appar ...

  3. LVM 逻辑卷学习

    一个执着于技术的公众号 前言 每个Linux使用者在安装Linux时都会遇到这样的困境:在为系统分区时,如何精确评估和分配各个硬盘分区的容量,因为系统管理员不但要考虑到 当前某个分区需要的容量,还要预 ...

  4. 一文彻底搞懂JavaScript中的prototype

    prototype初步认识 在学习JavaScript中,遇到了prototype,经过一番了解,知道它是可以进行动态扩展的 function Func(){}; var func1 = new Fu ...

  5. python常用标准库(math数学模块和random随机模块)

    常用的标准库 数学模块 import math ceil -- 上取整 对一个数向上取整(进一法),取相邻最近的两个整数的最大值. import math res = math.ceil(4.1) p ...

  6. 操作系统:Tails

    Tor是一个网络 如今,Tor浏览器可能是Tor的代言人,但Tor的真正力量在于Tor网络.大家都知道,"Tor"实际上是"The Onion Router"( ...

  7. 690. Employee Importance - LeetCode

    Question 690. Employee Importance Example 1: Input: [[1, 5, [2, 3]], [2, 3, []], [3, 3, []]], 1 Outp ...

  8. GDB的简单使用一

    GDB的简单使用一 一.概念 二.GDB的基本使用方法一 调试前预备知识 获取进程的内核转储 启动gdb调试 1.启动 2.设置断点 3.运行程序 4.显示栈帧 5.显示变量 6.显示寄存器 7.单步 ...

  9. 分布式机器学习:PageRank算法的并行化实现(PySpark)

    1. PageRank的两种串行迭代求解算法 我们在博客<数值分析:幂迭代和PageRank算法(Numpy实现)>算法中提到过用幂法求解PageRank. 给定有向图 我们可以写出其马尔 ...

  10. 《C Primer Plus》第六版笔记--1~3章

    目录 第一章 初识C语言 1 使用C语言的7个步骤 1.1 定义程序目标 1.2 设计程序(功能实现) 1.3 编写代码 1.4 编译 1.5 运行程序 1.6 测试和调试程序 1.7 维护和修改代码 ...