Submission #798123

#TimeUsernameProblemLanguageResultExecution timeMemory
798123finn__Diversity (CEOI21_diversity)C++17
100 / 100
6451 ms6532 KiB
#include <bits/stdc++.h> using namespace std; template <size_t N> struct OrSegmentTree { bitset<2 * N> t; bool operator[](size_t i) { return t[N + i]; } void reset() { t.reset(); } void set(size_t i, bool x) { t[i += N] = x; while (i >>= 1) t[i] = t[2 * i] | t[2 * i + 1]; } int64_t previous_nonzero(size_t i) { i += N; do { if ((i & 1) && t[i - 1]) { --i; while (i < N) i = 2 * i + t[2 * i + 1]; return i - N; } } while ((i >>= 1) > 1); return -1; } int64_t next_nonzero(size_t i) { i += N; do { if (!(i & 1) && t[i + 1]) { ++i; while (i < N) i = 2 * i + !t[2 * i]; return i - N; } } while ((i >>= 1) > 1); return N; } }; constexpr size_t N = 300000, K = 2400; uint32_t a[N], freq[N], freq_of_freq[N]; uint64_t ans[N]; tuple<size_t, size_t, size_t> queries[N]; OrSegmentTree<N> tree; inline uint64_t gauss(uint64_t n) { return (n * (n + 1)) / 2; } inline uint64_t range_gauss(uint64_t a, uint64_t b) { return gauss(b) - (a ? gauss(a - 1) : 0); } inline uint64_t sum_of_squares(uint64_t n) { return (n * (n + 1) * ((n << 1) + 1)) / 6; } inline uint64_t range_cost(uint64_t l0, uint64_t y, uint64_t z, uint64_t n) { return -range_gauss(l0, l0 + z * y - 1) - z * l0 * l0 - 2 * l0 * y * gauss(z - 1) - y * y * sum_of_squares(z - 1) + z * n * (l0 + y) + y * n * gauss(z - 1); } int main() { ios_base::sync_with_stdio(0); cin.tie(0); size_t n, q; cin >> n >> q; for (size_t i = 0; i < n; ++i) cin >> a[i], --a[i]; for (size_t i = 0; i < q; ++i) cin >> get<0>(queries[i]) >> get<1>(queries[i]), --get<0>(queries[i]), --get<1>(queries[i]), get<2>(queries[i]) = i; sort(queries, queries + q, [](auto const &a, auto const &b) { return get<0>(a) / K == get<0>(b) / K ? get<1>(a) > get<1>(b) : get<0>(a) < get<0>(b); }); size_t i = 0, j = 0; freq[a[0]] = 1; freq_of_freq[1] = 1; tree.set(freq[a[0]], 1); for (size_t k = 0; k < q; ++k) { auto const [u, v, qi] = queries[k]; while (j < v) { ++j; freq[a[j]]++; freq_of_freq[freq[a[j]] - 1]--; freq_of_freq[freq[a[j]]]++; if (!freq_of_freq[freq[a[j]] - 1]) tree.set(freq[a[j]] - 1, 0); if (freq_of_freq[freq[a[j]]] == 1) tree.set(freq[a[j]], 1); } while (i > u) { --i; freq[a[i]]++; freq_of_freq[freq[a[i]] - 1]--; freq_of_freq[freq[a[i]]]++; if (!freq_of_freq[freq[a[i]] - 1]) tree.set(freq[a[i]] - 1, 0); if (freq_of_freq[freq[a[i]]] == 1) tree.set(freq[a[i]], 1); } while (j > v) { freq_of_freq[freq[a[j]]]--; freq_of_freq[freq[a[j]] - 1]++; if (!freq_of_freq[freq[a[j]]]) tree.set(freq[a[j]], 0); if (freq_of_freq[freq[a[j]] - 1] == 1) tree.set(freq[a[j]] - 1, 1); freq[a[j]]--; --j; } while (i < u) { freq_of_freq[freq[a[i]]]--; freq_of_freq[freq[a[i]] - 1]++; if (!freq_of_freq[freq[a[i]]]) tree.set(freq[a[i]], 0); if (freq_of_freq[freq[a[i]] - 1] == 1) tree.set(freq[a[i]] - 1, 1); freq[a[i]]--; ++i; } vector<pair<uint64_t, uint64_t>> y; size_t i = tree.next_nonzero(0); while (i < N) { y.emplace_back(i, freq_of_freq[i]); i = tree.next_nonzero(i); } uint64_t lsum = 0, rsum = 0, cost = 0; for (auto const &[freq, num] : y) if (freq) { size_t num_left, num_right; if (lsum < rsum) num_right = num / 2, num_left = num - num_right; else num_left = num / 2, num_right = num - num_left; cost += range_cost(lsum, freq, num_left, v - u + 1); cost += range_cost((v - u + 1) - rsum - num_right * freq, freq, num_right, v - u + 1); lsum += num_left * freq; rsum += num_right * freq; } ans[qi] = cost; } for (size_t i = 0; i < q; ++i) 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...
#Verdict Execution timeMemoryGrader output
Fetching results...