제출 #827651

#제출 시각아이디문제언어결과실행 시간메모리
827651NeroZeinDiversity (CEOI21_diversity)C++17
4 / 100
1 ms340 KiB
#include "bits/stdc++.h" #define int long long using namespace std; #ifdef Nero #include "Deb.h" #else #define deb(...) #endif const int B = 550; const int N = 3e5 + 5; int a[N]; int freq[N]; int tot_freq[N]; int cnt_freq[N]; bool is_small[N]; long long prop_ps[N]; vector<int> large_vals; inline int64_t hilbertOrder(int x, int y, int pow, int rotate) { if (pow == 0) { return 0; } int hpow = 1 << (pow - 1); int seg = (x < hpow) ? ((y < hpow) ? 0 : 3) : ((y < hpow) ? 1 : 2); seg = (seg + rotate) & 3; const int rotateDelta[4] = {3, 0, 0, 1}; int nx = x & (x ^ hpow), ny = y & (y ^ hpow); int nrot = (rotate + rotateDelta[seg]) & 3; int64_t subSquareSize = int64_t(1) << (2 * pow - 2); int64_t ans = seg * subSquareSize; int64_t add = hilbertOrder(nx, ny, pow - 1, nrot); ans += (seg == 1 || seg == 2) ? add : (subSquareSize - add - 1); return ans; } struct Query{ int l, r, id; int64_t ord; inline void calcOrder() { ord = hilbertOrder(l, r, 18, 0); } }; inline bool operator<(const Query &x, const Query &y){ return x.ord < y.ord; } void modify(int i, int v) { if (freq[a[i]] && tot_freq[a[i]] <= B) { cnt_freq[freq[a[i]]]--; } freq[a[i]] += v; if (freq[a[i]] && tot_freq[a[i]] <= B) { cnt_freq[freq[a[i]]]++; } } vector<pair<int, int>> construct() { vector<pair<int, int>> left; vector<pair<int, int>> right; bool go_left = true; vector<pair<int, int>> xz; for (int i = 1; i <= B; ++i) { if (cnt_freq[i]) { xz.push_back({i, cnt_freq[i]}); } } for (int i : large_vals) { if (freq[i]) { xz.push_back({freq[i], 1}); } } for (auto [i, z] : xz) { int x = z / 2; int y = z - x; if ((x + y) % 2 == 0) { left.push_back({i, x}); right.push_back({i, x}); } else { if (go_left) { left.push_back({i, y}); if (x) { right.push_back({i, x}); } } else { if (x) { left.push_back({i, x}); } right.push_back({i, y}); } go_left ^= 1; } } vector<pair<int, int>> ret = left; reverse(right.begin(), right.end()); for (auto [x, y] : right) { if (ret.back().first == x) { ret.back().second += y; } else { ret.push_back({x, y}); } } return ret; } long long prop(int x) { return (long long) x * (x + 1) / 2; } long long get(vector<pair<int, int>> v) { long long last = 0; long long ret = 0; long long without = 0; long long normal_sum = 0; long long times_freq_sum = 0; for (int i = (int) v.size() - 1; i >= 0; --i) { long long tmp = 0; auto [element_freq, rep] = v[i]; long long z = rep - 1; tmp += element_freq * z * (z + 1) * (z + 2) / 6 * element_freq; tmp += last * element_freq * rep; tmp += normal_sum * element_freq * rep * (rep + 1) / 2; last = (rep - 1) * rep / 2 * element_freq + last + normal_sum * rep; ret += tmp; times_freq_sum += without * rep + prop(rep) * element_freq; without += prop(rep) * element_freq; normal_sum += v[i].first * v[i].second; } ret += prop(normal_sum); return ret; } signed main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n, q; cin >> n >> q; for (int i = 0; i < n; ++i) { cin >> a[i]; tot_freq[a[i]]++; } for (int i = 1; i < N; ++i) { if (tot_freq[i] > B) { large_vals.push_back(i); } } vector<Query> qs(q); for (int i = 0; i < q; ++i) { int l, r; cin >> l >> r; --l, --r; qs[i].l = l, qs[i].r = r; qs[i].id = i; qs[i].calcOrder(); } vector<long long> ans(q); int l = 0, r = -1; for (auto &pq : qs) { int ql = pq.l, qr = pq.r, id = pq.id; while (l > ql) modify(--l, 1); while (r < qr) modify(++r, 1); while (l < ql) modify(l++, -1); while (r > qr) modify(r--, -1); vector<pair<int, int>> v = construct(); ans[id] = get(v); } 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...