Submission #1235523

#TimeUsernameProblemLanguageResultExecution timeMemory
1235523BuiDucManh123Izbori (COCI22_izbori)C++20
110 / 110
163 ms56304 KiB
#include <bits/stdc++.h> #define int long long #define ll long long #define fi first #define se second #define pb push_back using namespace std; int n; vector<ll> raw; vector<int> a; vector<vector<vector<int>>> v; // v[parity][dish_id] → list of “half‐positions” vector<vector<map<int,int>>> cnt; // cnt[parity][dish_id][hei] → count ll ans = 0; int bua; void solve(int id, int k) { // “magic” offset so hei never goes negative const int ma = 250005; auto &vk = v[id][k]; int res = 0; // initial hei = ma − first_halfpos + 1 int hehe = ma - vk[0] + 1; int mi = hehe; for (int i = 0; i + 1 < (int)vk.size(); i++) { int pos = vk[i]; // map back to original index q in [1..n] int q = (pos - id) * 2 + id; // if the element at q equals this dish if (a[q] == k) { if (hehe <= ma) ans += cnt[id][k][hehe] + 1; else ans += cnt[id][k][hehe]; } // if two consecutive elements are equal, we “step up” hei if (a[q] == a[q+1]) { if (hehe <= ma) res += cnt[id][k][hehe] + 1; else res += cnt[id][k][hehe]; hehe++; } // record current hei cnt[id][k][hehe]++; ans += res * 2; if (q + 1 == n) ans -= res; // now “slide” hei back down, one step per gap until the next vk[i+1] int gap = vk[i+1] - vk[i] - 1; int t = min(hehe - mi, gap); bua = hehe - gap; while (t--) { hehe--; if (hehe <= ma) res -= cnt[id][k][hehe] + 1; else res -= cnt[id][k][hehe]; ans += res * 2; // adjust final correction if (n % 2 != id && hehe == bua && i == (int)vk.size() - 2) ans -= res; cnt[id][k][hehe]++; } // restore hei to bua for next iteration hehe = bua; mi = min(mi, hehe); } // handle the very last element if it sits at index n with this parity if (n % 2 == id && a[n] == k) { if (hehe <= ma) ans += cnt[id][k][hehe] + 1; else ans += cnt[id][k][hehe]; } } int32_t main(){ ios::sync_with_stdio(false); cin.tie(nullptr); // 1) Read cin >> n; raw.resize(n+1); for (int i = 1; i <= n; i++) { cin >> raw[i]; } // 2) Compress dish‐values into [0..U-1] vector<ll> comp(raw.begin()+1, raw.end()); sort(comp.begin(), comp.end()); comp.erase(unique(comp.begin(), comp.end()), comp.end()); int U = comp.size(); a.assign(n+2, 0); for (int i = 1; i <= n; i++) { a[i] = lower_bound(comp.begin(), comp.end(), raw[i]) - comp.begin(); } // 3) Resize our per‐dish data structures v .assign(2, vector<vector<int>>(U)); cnt .assign(2, vector<map<int,int>>(U)); // Build the lists of “half‐positions” for each (parity, dish) for (int i = 1; i < n; i++) { int id = i % 2; int x = a[i]; int y = a[i+1]; v[id][x].pb(i/2 + id); if (x != y) v[id][y].pb(i/2 + id); } // Append the virtual “end” marker for each dish for (int x = 0; x < U; x++) { v[1][x].pb(n/2 + 1); v[0][x].pb((n+1)/2); } // 4) Run solve() for every parity & every dish for (int id = 0; id < 2; id++) { for (int x = 0; x < U; x++) { solve(id, x); } } // 5) Output the answer 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...