ABC196E 题解
前言
很有趣的题,取决于思考方向。
思路
如果你一开始想着从 \(x\) 开始,将某些操作进行某些合并,再用某个数据结构维护,那么你做不出来。
正确的思考方向:将 \(x\) 认为是一个未知数,维护一个 \([\text{L}, \text{R}]\) 的范围。
- \(t_i = 1\),\([\text{L}, \text{R}] \to [\text{L}+a_i, \text{R}+a_i]\)。
- \(t_i = 2\),\([\text{L}, \text{R}] \to [\max(\text{L},a_i), \max(\text{R},a_i)]\)。
- \(t_i = 3\),\([\text{L}, \text{R}] \to [\min(\text{L},a_i), \min(\text{R},a_i)]\)。
对于一个 \(x\),先将 \(t_i=1\) 所增加偏移量补上。然后再把它限制进去 \([\text L,\text R]\) 里,即:答案为 \(\max(\text{L}, \min(\text{R}, x + \text{add})\)。
代码
#include <iostream>
#include <cstdio>
using namespace std;
long long min(long long x, int y) {return x < y ? x : y;}
long long max(long long x, int y) {return x > y ? x : y;}
int main()
{
int n, q; long long minx = -1e18, maxx = 1e18, add = 0;
scanf("%d", &n);
while (n--)
{
int x, op;
scanf("%d%d", &x, &op);
if (op == 1) minx += x, maxx += x, add += x;
else if (op == 2) minx = max(minx, x), maxx = max(maxx, x);
else if (op == 3) minx = min(minx, x), maxx = min(maxx, x);
}
scanf("%d", &q);
while (q--)
{
int x; scanf("%d", &x);
printf("%lld\n", max(minx, min(maxx, x + add)));
}
return 0;
}
希望能帮助到大家!