N = read(); M = read(); for (registerint i = 1; i <= M; i++) HP[i] = 3;//HP 数组存血量 for (registerint i = 1; i <= N; i++) { int x, y; x = read(); y = read(); q[i].u = x; q[i].v = y;//q 数组用来存每条大新闻 if (HP[x] && HP[y])//如果这条新闻是有效的 { HP[y]--; if (HP[y] == 0) { die[y] = i;//die 数组存每个人是什么时候死的 } } if (HP[x] == 1) { v[x].push_back(MP(lst[x], i - 1));//v 存每个人的等价区间们 //lst 存每个人的上一步行动是在什么时候 v[x].push_back(MP(i, i)); lst[x] = i + 1; } } int remain = 0;//如果没有开挂,本应有 remain 人存活 for (registerint i = 1; i <= M; i++) { if (HP[i]) remain++; if (lst[i] != N + 1)//处理一些还未封闭的等价区间 v[i].push_back(MP(lst[i], N)); if (die[i] == 0) die[i] = N + 5;//如果一直不死,就给他赋一个无限晚的死亡时间 }
#include<bits/stdc++.h> usingnamespace std; #define endl '\n' constint MAX = 1e5 + 7; constint MOD = 1e9 + 7; voidprint(bool a) { cout << (a ? "YES" : "NO") << endl; } structatk { int u, v; } q[MAX]; #define PII pair<int, int> #define MP make_pair vector<PII> v[MAX]; intread() { int num = 0, bj = 1; char ch = getchar(); while (!isdigit(ch)) { if (ch == '-') { bj = -1; } ch = getchar(); } while (isdigit(ch)) { num = num * 10 + ch - '0'; ch = getchar(); } return bj * num; } int lst[MAX]; int die[MAX], HP[MAX]; int ans[MAX]; int N, M; inlineintcheck(int pos, int v)//在 pos 号大新闻后,v 被砍了一刀 { for (registerint i = 1; i <= M; i++) HP[i] = 3; for (registerint i = 1; i <= pos; i++) if (HP[q[i].u] && HP[q[i].v]) HP[q[i].v]--; if (HP[v])//开挂砍一刀 HP[v]--; for (registerint i = pos + 1; i <= N; i++) (HP[q[i].u] && HP[q[i].v]) HP[q[i].v]--; int tmp = 0; for (registerint i = 1; i <= M; i++) tmp += (HP[i] > 0);//统计存活人数 return tmp; } signedmain() { ...//预处理部分,在此不再重复 for (registerint i = 1; i <= M; i++)//枚举人 { for (auto u : v[i])//枚举等价区间 { if (u.first > u.second) //若区间不合法则跳过(推测应该是在造区间的时候造了一些没用的区间) continue; if (die[i] <= u.first)//若是鞭尸 ans[remain] += u.second - u.first + 1; else ans[check(u.second, i)] += u.second - u.first + 1; } } for (registerint i = 0; i <= M; i++) printf("%d ", ans[i]); return0; }