10.24训练赛
这次我们A水题的速度非常快, 大概1个多小时作业, A了7道题, (zsyA掉了莫比乌斯%%%), 但后面竟然一道题也没想出来, 非常不应该。。
H. Haunted House
当时看到这道题的时候确实想了很长时间, 也有了一些思路, 但以为是个高级的数据结构, 就没有写出来。 还是直接说正解把, 首先, 每个人至多被一个鬼吓住, 而一个鬼可以吓住多个人, 所以我们去找每个人会被那个鬼吓住, 不如去找每个鬼能吓住多少人, 那么这个就比较容易一点了, 因为每个鬼活跃的时间都是固定的, 如果抓到人, 更新鬼的活跃时间就行了, 人直接淘汰掉, 而枚举人的话总不能把鬼淘汰了把, set可以解决, 至于复杂度的话, 假如一个鬼活跃时间为x, 总时间为T, 那活跃的时间段的个数是\(T/x\),由于每个鬼活跃的时间是个排列(x <= n),总时间就是\(Tlogm\), 在加上set\(logn\)的复杂度, 总时间复杂度为\((Tlogmlogn)\)
这道题还让我复习了一下set的用法, 不失为一道好题
(注:部分内容借鉴gcf博客)
点击查看代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
template < typename T > inline void read(T &x) {
x = 0; T ff = 1, ch = getchar();
while (!isdigit(ch)) {
if (ch == '-') ff = -1;
ch = getchar();
}
while (isdigit(ch)) {
x = (x << 1) + (x << 3) + (ch ^ 48);
ch = getchar();
}
x *= ff;
}
int n, m, p[N];
set < pair < int, int > > s;
pair < int, int > ans[N];
int main() {
read(n), read(m);
for (int i = 0; i < n; ++i) read(p[i]);
for (int i = 0; i < m; ++i) {
int x; read(x);
s.insert({x, i});
}
for (int i = 0; i < n; ++i) {
int cnt = 0;
while (true) {
set < pair < int, int > > ::iterator it = s.lower_bound({cnt - i, -1});
if (it == s.end()) break;
pair < int, int > x = *it;
if (x.first <= cnt - i + p[i] - 1) {
s.erase(it);
ans[x.second].first = i;
ans[x.second].second = x.first + i;
cnt = x.first + p[i] + i + 1;
} else cnt += 2 * p[i];
}
}
for (set < pair < int, int > > ::iterator it = s.begin(); it != s.end(); ++it) {
pair < int, int > x = *it;
ans[x.second].first = ans[x.second].second = -1;
}
for (int i = 0; i < m; ++i)
printf("%d %d\n", ans[i].first, ans[i].second);
return 0;
}