题目:2024.11.17 题目

覆盖

的坐标轴上有 个区间,第 个区间为 。现在你需要去掉一部分区间,使区间 与任意一个原本的区间不重叠。第 个区间删去代价为 ,求满足条件需要的最少代价。


首先,我们对区间以 为关键字从小至大进行排序,然后枚举 ,尝试答案区间为 需要的代价。由于 ,因此只有 的区间 可能会与 重叠。但是,我们发现这里重叠的标准是 是否小于 ,不妨在 上面下功夫。

新建另一个区间序列 ,将 赋值为 ,对 为关键字从小至大排序,此时我们就可以极快地通过二分求出哪一段的 了。此时我们发现当 时即使 也不会与我们的答案区间重叠,而原序列又是按照 进行排序的,因此我们直接新建变量满足 的区间 记录下来,求答案时需要减去。

最后对于所有的答案区间进行求值即可。时间复杂度 。注意 也是一个可选的答案区间,不能忽略,否则会失分。

#include <fstream>
#include <algorithm>
 
using namespace std;
using LL = long long;
 
const LL kMaxN = 1e5 + 5;
 
ifstream cin("cover.in");
ofstream cout("cover.out");
 
struct Interval {
  LL l, r, p;
 
  bool operator<(const Interval &that) {
    return l < that.l;
  }
} a[kMaxN], b[kMaxN];
 
LL p[kMaxN], n, w, c, sub, ans = 1e18;
 
LL calc(LL x) {
  LL y = lower_bound(b + 1, b + n + 1, Interval{x, x, x}) - b - 1;
  return p[y] - sub;
}
 
int main() {
  cin.tie(0)->sync_with_stdio(0);
  cin >> n >> w >> c;
  for (LL i = 1; i <= n; i++) {
    cin >> a[i].l >> a[i].r >> a[i].p;
    b[i] = a[i];
  }
  sort(a + 1, a + n + 1, [](auto a, auto b) { return a.r < b.r; });
  sort(b + 1, b + n + 1);
  for (LL i = 1; i <= n; i++) {
    p[i] = p[i - 1] + b[i].p;
  }
  ans = min(ans, calc(c));
  for (LL i = 1; i <= n; i++) {
    if (a[i].r + c <= w) {
      sub += a[i].p;
      ans = min(ans, calc(a[i].r + c));
    }
  }
  cout << ans << '\n';
  return 0;
}

分发传单

最开始有 代生物。有 秒的时间可以让他们工作,第 代生物可以进行如下工作:花费 秒分发 张传单或花费 秒繁殖一个第 代的生物。多个生物可以同时工作,求 秒内可以分发的传单的数量的最大值。


题目完全看懂了,但是对于小至 的数据仍然毫无头绪,代码都没输入,文件都没有创建,本题成功获得 分。

后记:XBC 是机房内唯一一个使用 dp 的,获得 分,本机房最高分。

pic_center

绘画

个格子,进行 次涂色,第 将任意连续 个格子染黑,若已经被染黑则颜色不变。求最后得到不同的结果的数量,答案为 取模。


采用最垃圾的手段进行骗分。对于 的特殊情况,也就是只会涂一次颜色,那么显然不会出现任何一个格子被重复填色的情况,因此答案即为 。成功获得 分。

后记:HHC 推公式 AC 掉了 的所有测试点,太巨了。

三角覆盖

给出一个直角边长为  的等腰直角三角形点集,共有  行,第  行的点为 

有  次覆盖操作,每次覆盖一个等腰直角三角形区域内的点,第  次给出  个数 ,表示对于 ,点  被覆盖了。

随后给出  次询问操作,询问一个等腰直角三角形区域内未被覆盖的点数,第  次给出  个数 ,表示询问所有 ,点  有多少未被覆盖。


采用差分+前缀和的方式对于 的数据进行处理。

较小的时候,我们可以对于每一次处理都枚举每一行,但是不能枚举修改的三角形当中的每一个点。因此不难想出对于每一行进行序列差分。

但是我们需要考虑的很重要一个点,就是我们的差分是对一个区间的每一个元素进行相加,而非将区间内的每一个元素标记为 。这该怎么整呢?

实际上,我们还是正常地进行差分(区间都加 ),但是利用前缀和还原之后对于每一个不为 的元素其实就是 (原本的值代表它被标记了几次,而只要被标记了正整数次就是被覆盖),否则为

然后再进行一次每行的前缀和。这样子我们的查询操作也能做到 。该算法的总时间复杂度为 ,成功获得 分。