#include <bits/stdc++.h>
using namespace std;
const int N = 200'007;
int n, m, k;
long long ans[N];
int tmp_result;
vector <int> G[N];
vector <tuple <int, int, int> > edges;
int par[N];
int can_reach[N];
int to_edge(int id)
{
const auto &[u, v, s] = edges[id];
return s ? u : v;
}
void add_edge(int u, int v)
{
G[u].push_back(edges.size());
G[v].push_back(edges.size());
edges.push_back({u, v, 0});
}
void dfs(int u)
{
can_reach[u] = tmp_result;
for (const auto &e: G[u]) {
int v = to_edge(e);
if (can_reach[v] != tmp_result) {
par[v] = e;
dfs(v);
}
}
}
void solve(int s)
{
for (auto &[u, v, c]: edges) {
c = 0;
}
tmp_result = 0;
for (int i = 1; i <= n + n; ++i) {
can_reach[i] = -1;
}
dfs(0);
int last = s;
for (int i = s; i <= n; ++i) {
if (can_reach[i] != tmp_result) {
continue;
}
ans[tmp_result] += i - last;
last = i;
tmp_result++;
int cur = i;
while (cur) {
get <2> (edges[par[cur]]) ^= 1;
cur = to_edge(par[cur]);
}
dfs(0);
}
ans[tmp_result] += n + 1 - last;
}
int main()
{
scanf("%d %d %d", &n, &m, &k);
for (int i = 1; i <= m; ++i) {
int u, v;
scanf("%d %d", &u, &v);
if (v > k) {
add_edge(u, n + v);
}
}
for (int i = 1; i <= n; ++i) {
if (i <= k) {
add_edge(0, n + i);
}
add_edge(n + i, i);
}
for (int i = k + 1; i <= n; ++i) {
solve(i);
}
for (int i = 0; i <= k; ++i) {
printf("%lld\n", ans[i]);
}
return 0;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 | #include <bits/stdc++.h> using namespace std; const int N = 200'007; int n, m, k; long long ans[N]; int tmp_result; vector <int> G[N]; vector <tuple <int, int, int> > edges; int par[N]; int can_reach[N]; int to_edge(int id) { const auto &[u, v, s] = edges[id]; return s ? u : v; } void add_edge(int u, int v) { G[u].push_back(edges.size()); G[v].push_back(edges.size()); edges.push_back({u, v, 0}); } void dfs(int u) { can_reach[u] = tmp_result; for (const auto &e: G[u]) { int v = to_edge(e); if (can_reach[v] != tmp_result) { par[v] = e; dfs(v); } } } void solve(int s) { for (auto &[u, v, c]: edges) { c = 0; } tmp_result = 0; for (int i = 1; i <= n + n; ++i) { can_reach[i] = -1; } dfs(0); int last = s; for (int i = s; i <= n; ++i) { if (can_reach[i] != tmp_result) { continue; } ans[tmp_result] += i - last; last = i; tmp_result++; int cur = i; while (cur) { get <2> (edges[par[cur]]) ^= 1; cur = to_edge(par[cur]); } dfs(0); } ans[tmp_result] += n + 1 - last; } int main() { scanf("%d %d %d", &n, &m, &k); for (int i = 1; i <= m; ++i) { int u, v; scanf("%d %d", &u, &v); if (v > k) { add_edge(u, n + v); } } for (int i = 1; i <= n; ++i) { if (i <= k) { add_edge(0, n + i); } add_edge(n + i, i); } for (int i = k + 1; i <= n; ++i) { solve(i); } for (int i = 0; i <= k; ++i) { printf("%lld\n", ans[i]); } return 0; } |
English