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 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
| #include <bits/stdc++.h>
using pii = std::pair<int, int>;
const int kMaxN = 4e5 + 5;
int n, m, k; int l[kMaxN], r[kMaxN], id[kMaxN], pre[kMaxN];
struct Tree { int lim, res, dfn_cnt, dfn[kMaxN], st[kMaxN][20], cnt[kMaxN]; std::vector<int> G[kMaxN];
int get(int x, int y) { return dfn[x] < dfn[y] ? x : y; } void dfs(int u, int fa) { st[dfn[u] = ++dfn_cnt][0] = fa; for (auto v : G[u]) { if (v == fa) continue; dfs(v, u); } } int LCA(int x, int y) { if (x == y) return x; if (dfn[x] > dfn[y]) std::swap(x, y); int k = std::__lg(dfn[y] - dfn[x]); return get(st[dfn[x] + 1][k], st[dfn[y] - (1 << k) + 1][k]); } void build() { for (int i = 1; i <= 2 * m; ++i) G[pre[i]].emplace_back(i); dfs(0, 2 * m + 1); for (int i = 1; i <= std::__lg(2 * m + 1); ++i) for (int j = 1; j <= 2 * m + 1 - (1 << i) + 1; ++j) st[j][i] = get(st[j][i - 1], st[j + (1 << (i - 1))][i - 1]); } void upd(int x, int v) { if (x < lim) res += v; else cnt[x] += v; } void setlim(int _lim) { for (; lim < _lim; ++lim) res += cnt[lim]; } int query() { return res; } } tr;
struct ODT { bool op = 0; std::set<std::pair<int, int>> st; void init(int n, bool _op) { st.clear(), st.emplace(1, 0), st.emplace(n + 1, 0); op = _op; if (op) tr.upd(0, n - 1); } void split(int x) { auto it = --st.lower_bound({x + 1, 0}); if (x != it->first) st.emplace(x, it->second); } int getval(int x) { return (--st.lower_bound({x + 1, 0}))->second; } void upd(int l, int r, int v) { split(l), split(r + 1); std::vector<std::pair<int, int>> vec; for (auto it = st.lower_bound({l, 0}); it->first != r + 1; ++it) vec.emplace_back(*it); int pre = -1, nxt = -1; if (l > 1) pre = getval(l - 1); if (r < n) nxt = getval(r + 1); for (int i = 0; i < vec.size(); ++i) { int cnt = (i + 1 == vec.size() ? (r + 1) : vec[i + 1].first) - vec[i].first; if (op) { tr.upd(vec[i].second, -(cnt - 1)); if (i) tr.upd(tr.LCA(vec[i].second, vec[i - 1].second), -1); else if (l > 1) tr.upd(tr.LCA(vec[i].second, pre), -1); if (i + 1 == vec.size() && r < n) tr.upd(tr.LCA(vec[i].second, nxt), -1); } } for (auto p : vec) st.erase(p); st.emplace(l, v); if (op) { tr.upd(v, r - l); if (l > 1) tr.upd(tr.LCA(v, pre), 1); if (r < n) tr.upd(tr.LCA(v, nxt), 1); } } } odt;
void dickdreamer() { std::cin >> n >> m >> k; for (int i = 1; i <= m; ++i) { std::cin >> l[i] >> r[i]; l[i + m] = l[i], r[i + m] = r[i]; } odt.init(n, 0); for (int i = 1; i <= 2 * m; ++i) { pre[i] = odt.getval(l[i]); odt.upd(l[i], r[i], i); } tr.build(), odt.init(n, 1); for (int i = 1; i <= 2 * m; ++i) { odt.upd(l[i], r[i], i), tr.setlim(i - k + 1); if (i >= k && i <= k + m - 1) std::cout << tr.query() + 1 << ' '; } }
int32_t main() { #ifdef ORZXKR freopen("in.txt", "r", stdin); freopen("out.txt", "w", stdout); #endif std::ios::sync_with_stdio(0), std::cin.tie(0), std::cout.tie(0); int T = 1; while (T--) dickdreamer(); return 0; }
|