Submission #46739

#TimeUsernameProblemLanguageResultExecution timeMemory
46739qoo2p5Rope (JOI17_rope)C++14
80 / 100
968 ms83568 KiB
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int INF = (int) 1e9 + 1e6 + 123; const ll LINF = (ll) 1e18 + 1e9 + 123; #define rep(i, s, t) for (auto i = (s); i < (t); ++(i)) #define per(i, s, t) for (auto i = (s); i >= (t); --(i)) #define all(x) (x).begin(), (x).end() #define sz(x) ((int)(x).size()) #define mp make_pair #define pb push_back bool mini(auto &x, const auto &y) { if (y < x) { x = y; return 1; } return 0; } bool maxi(auto &x, const auto &y) { if (y > x) { x = y; return 1; } return 0; } void run(); int main() { ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); run(); return 0; } const int N = 1 << 20; int n, m; int a[N]; int tree[2 * N + 239]; int cnt_full[N + 239]; vector<int> match[N + 239]; void clr() { memset(tree, 0, sizeof tree); memset(cnt_full, 0, sizeof cnt_full); rep(i, 0, m) { match[i].clear(); } } void add(int i, int tl, int tr, int ind, int val) { if (m > 5000) return; if (tl == tr - 1) { tree[i] += val; return; } int tm = (tl + tr) / 2; if (ind < tm) add(2 * i + 1, tl, tm, ind, val); else add(2 * i + 2, tm, tr, ind, val); tree[i] = max(tree[2 * i + 1], tree[2 * i + 2]); } void add(int ind, int val) { add(0, 0, N, ind, val); } int get(int i, int tl, int tr, int l, int r) { if (m > 5000) return 0; if (tl >= r || tr <= l) { return -INF; } if (l <= tl && tr <= r) { return tree[i]; } int tm = (tl + tr) / 2; return max(get(2 * i + 1, tl, tm, l, r), get(2 * i + 2, tm, tr, l, r)); } int get(int l, int r) { return get(0, 0, N, l, r + 1); } int ans[N]; void run() { cin >> n >> m; if (m == 1) { cout << "0\n"; return; } rep(i, 0, n) { cin >> a[i]; a[i]--; } rep(i, 0, m) { ans[i] = INF; } int qq = 0; rep(odd_l, 0, 2) { rep(odd_r, 0, 2) { if ((odd_l + odd_r) % 2 != n % 2) { continue; } clr(); qq++; for (int i = odd_l; i < n - odd_r; i += 2) { if (a[i] != a[i + 1]) { match[a[i]].pb(a[i + 1]); match[a[i + 1]].pb(a[i]); } else { cnt_full[a[i]]++; } } rep(i, 0, m) { add(i, sz(match[i]) + 2 * cnt_full[i] + (odd_l && a[0] == i) + (odd_r && a[n - 1] == i)); } rep(i, 0, m) { int bonus = (odd_l && a[0] == i) + (odd_r && a[n - 1] == i); int we = bonus + cnt_full[i] * 2; int simple = 0; for (int j : match[i]) { add(j, -1); we++; simple++; } int other = max(get(0, i - 1), get(i + 1, m - 1)); assert(other >= 0); if (other == 0) { if (simple > 0) { we--; other++; } else if (bonus > 0) { we--; other++; } else { //~ assert(false); } } mini(ans[i], n - (we + other)); for (int j : match[i]) { add(j, 1); } } } } assert(qq <= 2); rep(i, 0, m) { cout << ans[i] << "\n"; } }
#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...