【BZOJ5034】【JSOI2014】Opera Performance

【Title link】

【Key points of thinking】

  • Give each actor a color, and JYY, an actor of the same color, can't tell the difference for the time being.
  • When operating, first sort the operation set by color, and deal with the operated actors of the same color respectively.
  • For each color, re-dye the operated actor to distinguish it from the unoperated actor. If the number of operated actors or unoperated actors at this time is one, then he will be recognized by JYY at this time. out.
  • You can use std::set to maintain a collection of actors of the same color, supporting addition and deletion.
  • Time complexity \(O(NLogN)\) (\(N\), \(M\), \(\sum K\) of the same order).

【Code】

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 100005;
template <typename T> void chkmax(T &x, T y) {x = max(x, y); }
template <typename T> void chkmin(T &x, T y) {x = min(x, y); }
template <typename T> void read(T &x) {
	x = 0; int f = 1;
	char c = getchar();
	for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
	for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
	x *= f;
}
template <typename T> void write(T x) {
	if (x < 0) x = -x, putchar('-');
	if (x > 9) write(x / 10);
	putchar(x % 10 + '0');
}
template <typename T> void writeln(T x) {
	write(x);
	puts("");
}
set <int> num[MAXN];
int n, m, tot;
int col[MAXN], pos[MAXN], ans[MAXN];
bool cmp(int x, int y) {return col[x] < col[y]; }
int main() {
	read(n), read(m);
	to = 1;
	for (int i = 1; i <= n; i++) {
		col[i] = 1;
		num[1].insert(i);
	}
	for (int i = 1; i <= m; i++) {
		int k; read(k);
		for (int j = 1; j <= k; j++)
			read(pos[j]);
		pos[k + 1] = 0;
		sort(pos + 1, pos + k + 1, cmp);
		for (int j = 1; j <= k; j++) {
			int now = col[pos[j]], from = j;
			while (col[pos[j + 1]] == now) j++;
			int cnt = j - from + 1;
			if (num[now].size() != cnt) {
				to++;
				for (int l = from; l <= j; l++) {
					int tmp = pos[l];
					col [tmp] = tot;
					num[now].erase(tmp);
					num[tot].insert(tmp);
				}
				if (num[now].size() == 1 && ans[*num[now].begin()] == 0) ans[*num[now].begin()] = i;
				if (num[tot].size() == 1 && ans[*num[tot].begin()] == 0) ans[*num[tot].begin()] = i;
			}
		}
	}
	for (int i = 1; i <= n - 1; i++)
		printf("%d ", ans[i]);
	printf("%d\n", ans[n]);
	return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324735100&siteId=291194637