【题目链接】
【思路要点】
- 给每个演员记一种颜色,同色的演员JYY暂时无法分辨。
- 操作时先对操作集合按颜色排序,分别处理同色的被操作的演员。
- 对于每一种颜色,将被操作的演员重新染色,与未被操作的演员区分开来,若此时被操作的演员或未被操作的演员个数为一,那么他此时会被JYY认出。
- 可以用std::set维护同色演员集合,支持加入和删除。
- 时间复杂度\(O(NLogN)\)(\(N\),\(M\),\(\sum K\)同阶)。
【代码】
#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); tot = 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) { tot++; 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; }