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
", ans[i].first, ans[i].second);
	return 0;
} 
原文地址:https://www.cnblogs.com/AK-ls/p/15465247.html