Submission #1279209

#TimeUsernameProblemLanguageResultExecution timeMemory
1279209MisterReaperRope (JOI17_rope)C++20
100 / 100
1916 ms117224 KiB
// File rope.cpp created on 14.10.2025 at 17:22:16 #include <bits/stdc++.h> using i64 = long long; #ifdef DEBUG #include "/home/ahmetalp/Desktop/Workplace/debug.h" #else #define debug(...) void(23) #endif #define def int mid = (l + r) >> 1, lv = v + 1, rv = v + ((mid - l + 1) << 1) struct segtree { struct node { int sm = 0; int mx = 0; void modify(int x) { sm += x; mx += x; } }; node unite(const node lhs, const node rhs) { node res; res.sm = lhs.sm + rhs.sm; res.mx = std::max(lhs.mx, rhs.mx); return res; } int n; std::vector<node> tree; segtree(int n_) : n(n_), tree(n << 1) {} void modify(int v, int l, int r, int p, int x) { if (l == r) { tree[v].modify(x); return; } def; if (p <= mid) { modify(lv, l, mid, p, x); } else { modify(rv, mid + 1, r, p, x); } tree[v] = unite(tree[lv], tree[rv]); } void modify(int p, int x) { modify(0, 0, n - 1, p, x); } node get(int v, int l, int r, int ql, int qr) { if (ql == l && r == qr) { return tree[v]; } def; if (qr <= mid) { return get(lv, l, mid, ql, qr); } else if (mid + 1 <= ql) { return get(rv, mid + 1, r, ql, qr); } else { return unite(get(lv, l, mid, ql, mid), get(rv, mid + 1, r, mid + 1, qr)); } } node get(int l, int r) { return get(0, 0, n - 1, l, r); } }; int main() { std::ios::sync_with_stdio(false); std::cin.tie(nullptr); int N, M; std::cin >> N >> M; std::vector<int> A(N); for (int i = 0; i < N; ++i) { std::cin >> A[i]; --A[i]; } std::vector<int> overall(N); for (int i = 0; i < N; ++i) { overall[A[i]] += 1; } // 1: First is single // 2: First and second is united int now1 = 0, now2 = 0; segtree cnt1(M), cnt2(M); std::vector<int> bad1(N), bad2(N); std::vector<int> typ1(N, 1), typ2(N, 1); auto Modify1 = [&](int p, int x) { int id = (p + 1) / 2; { if (id == 0 || (N % 2 == 0 && id == N / 2)) { if (bad1[id] == 0) { // ok } else { cnt1.modify(A[p], -1); } } else { if (bad1[id] == 0) { // ok } else if (bad1[id] == 1) { now1 -= 1; } else { cnt1.modify(A[2 * id - 1], -1); cnt1.modify(A[2 * id], -1); } } bad1[id] -= !typ1[p]; } typ1[p] = x; { bad1[id] += !typ1[p]; if (id == 0 || (N % 2 == 0 && id == N / 2)) { if (bad1[id] == 0) { // ok } else { cnt1.modify(A[p], +1); } } else { if (bad1[id] == 0) { // ok } else if (bad1[id] == 1) { now1 += 1; } else { cnt1.modify(A[2 * id - 1], +1); cnt1.modify(A[2 * id], +1); } } } }; auto Modify2 = [&](int p, int x) { int id = p / 2; { if (N % 2 == 1 && id == (N - 1) / 2) { if (bad2[id] == 0) { // ok } else { cnt2.modify(A[p], -1); } } else { if (bad2[id] == 0) { // ok } else if (bad2[id] == 1) { now2 -= 1; } else { cnt2.modify(A[2 * id], -1); cnt2.modify(A[2 * id + 1], -1); } } bad2[id] -= !typ2[p]; } typ2[p] = x; { bad2[id] += !typ2[p]; if (N % 2 == 1 && id == (N - 1) / 2) { if (bad2[id] == 0) { // ok } else { cnt2.modify(A[p], +1); } } else { if (bad2[id] == 0) { // ok } else if (bad2[id] == 1) { now2 += 1; } else { cnt2.modify(A[2 * id], +1); cnt2.modify(A[2 * id + 1], +1); } } } }; for (int i = 0; i < N; ++i) { Modify1(i, 0); Modify2(i, 0); } std::vector<std::vector<int>> ids(M); for (int i = 0; i < N; ++i) { ids[A[i]].emplace_back(i); } for (int c = 0; c < M; ++c) { int ans = N - overall[c]; if (c != 0) { for (auto i : ids[c - 1]) { Modify1(i, 0); Modify2(i, 0); } } for (auto i : ids[c]) { Modify1(i, 1); Modify2(i, 1); } debug(c); debug(typ1); debug(typ2); debug(bad1); debug(bad2); auto nd1 = cnt1.get(0, M - 1); auto nd2 = cnt2.get(0, M - 1); debug(now1, nd1.sm, nd1.mx); #ifdef DEBUG for (int i = 0; i < M; ++i) { auto nd = cnt1.get(i, i); std::cerr << nd.sm << " \n"[i == M - 1]; } #endif debug(now2, nd2.sm, nd2.mx); #ifdef DEBUG for (int i = 0; i < M; ++i) { auto nd = cnt2.get(i, i); std::cerr << nd.sm << " \n"[i == M - 1]; } #endif ans = std::min(ans, now1 + nd1.sm - nd1.mx); ans = std::min(ans, now2 + nd2.sm - nd2.mx); std::cout << ans << '\n'; } return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...