Submission #799711

#TimeUsernameProblemLanguageResultExecution timeMemory
799711JohannDiversity (CEOI21_diversity)C++14
0 / 100
1 ms340 KiB
#include "bits/stdc++.h" using namespace std; typedef long long ll; typedef vector<ll> vi; typedef pair<ll, ll> pii; typedef vector<pii> vpii; #define sz(x) (int)(x).size() #define all(x) (x).begin(), (x).end() const ll INF = 1e18; int N, Q; int A[300007]; ll ans[50005]; int freq[300007]; int cnt[300007]; unordered_set<int> S; int stuff[300007]; int idx; ll tmp; int pref, suff, n; struct query { int l, r, idx; }; ll numberOfSubsequences(ll x) { return x * (x + 1) / 2; } ll totalLengthOfSubsequences(ll x) { return x * (x + 1) * (x + 2) / 6; // return x * (x + 1) * (x + 1) / 2 - (2 * x + 1) * (x + 1) * x / 6; } void doStuff(ll x, ll y) { ll len = x * y; // if both are in set // tmp += x * x * (totalLengthOfSubsequences(y) - y) + y * numberOfSubsequences(x); tmp += x * x * (totalLengthOfSubsequences(y) - y) + y * x * (x + 1) / 2; // if one is inside the other isn't tmp += (n - len) * (x * y * (y + 1) / 2); // if both are outside tmp += y * pref * (n - pref - len); pref += len; swap(pref, suff); } struct segtree { int arr[1 << 20]; int size; void init(int _size) { size = 1; while (size < _size) size *= 2; fill(arr, arr + 2 * size, 0); } void add(int i, int v) { i += size; while (i > 0) { arr[i] += v; i /= 2; } } void dfs(int x) { if (arr[x] == 0) return; if (x < size) { dfs(2 * x); dfs(2 * x + 1); } else { // arr[x] := how often doStuff(x - size, (arr[x] + 1) / 2); if (arr[x] > 1) { doStuff(x - size, arr[x] / 2); if (arr[x] & 1) swap(pref, suff); } } } }; segtree seg; void add(int x) { if (freq[x] > 0) { // seg.add(freq[x], -1); --cnt[freq[x]]; // if (cnt[freq[x]] == 0) // S.erase(freq[x]); } ++freq[x]; // seg.add(freq[x], 1); ++cnt[freq[x]]; if (cnt[freq[x]] == 1) stuff[idx++] = freq[x]; } void sub(int x) { // seg.add(freq[x], -1); --cnt[freq[x]]; // if (cnt[freq[x]] == 0) // S.erase(freq[x]); --freq[x]; if (freq[x]) { // seg.add(freq[x], 1); ++cnt[freq[x]]; if (cnt[freq[x]] == 1) stuff[idx++] = freq[x]; } } int main() { ios::sync_with_stdio(false); cin.tie(0); cin >> N >> Q; for (int i = 0; i < N; ++i) cin >> A[i]; vector<query> Qu(Q); for (int i = 0; i < Q; ++i) cin >> Qu[i].l >> Qu[i].r, Qu[i].idx = i, --Qu[i].l; int sq = ceil(sqrt(N)); auto cmp = [&](const query &a, const query &b) { if (a.l / sq == b.l / sq) return a.r < b.r; else return a.l < b.l; }; sort(all(Qu), cmp); int lx = 0, rx = 0; fill(freq, freq + *max_element(A, A + N) + 1, 0); fill(cnt, cnt + N + 3, 0); seg.init(N + 1); for (query q : Qu) { while (rx < q.r) add(A[rx++]); while (lx > q.l) add(A[--lx]); while (rx > q.r) sub(A[--rx]); while (lx < q.l) sub(A[lx++]); n = q.r - q.l; pref = 0, suff = 0; tmp = 0; for (int i = 0; i < idx;) { if (cnt[stuff[i]] == 0) swap(stuff[i], stuff[--idx]); else ++i; } sort(stuff, stuff + idx); for (int i = 0; i < idx; ++i) { ll x = stuff[i]; if (i > 0 && stuff[i] == stuff[i - 1]) { stuff[i] = N + 1; continue; } doStuff(x, (cnt[x] + 1) / 2); if (cnt[x] > 1) { doStuff(x, cnt[x] / 2); if (cnt[x] & 1) swap(pref, suff); } } ans[q.idx] = tmp; } for (int i = 0; i < Q; ++i) cout << ans[i] << "\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...
#Verdict Execution timeMemoryGrader output
Fetching results...