제출 #1161674

#제출 시각아이디문제언어결과실행 시간메모리
1161674antonnDiversity (CEOI21_diversity)C++20
4 / 100
0 ms328 KiB
#include <bits/stdc++.h> #define F first #define S second using namespace std; using ll = long long; using pi = pair<int, int>; using vi = vector<int>; template<class T> bool ckmin(T& a, T b) { return b < a ? a = b, true : false; } template<class T> bool ckmax(T& a, T b) { return a < b ? a = b, true : false; } const int N = 3e5 + 7; const int K = 550; int a[N], cnt[N]; /** 10 1 1 3 3 2 1 3 3 1 1 3 1 10 6 1 2 4 3 5 4 3 1 6 **/ int f[N], small[K], taken[K]; multiset<int> s; void change(int x, int sgn) { if (f[x] >= K) { s.erase(s.find(f[x])); } else { --small[f[x]]; } f[x] += sgn; if (f[x] >= K) { s.insert(f[x]); } else { ++small[f[x]]; } } ll get(ll sum, ll x, ll total, ll cnt) { // (pref + j) * (total - pref - j) // (pref + 2 * j) * (total - pref - 2 * j) // (pref + 3 * j) * (total - pref - 3 * j) // pref * total - pref^2 - pref*j + j * total - j * pref - j^2 // pref * total + j * total - pref * (pref + j + j) - j^2 // total * (pref + j) - pref * (pref + 2*j) - j^2 // (pref + 2 * j) * (total - pref - 2 * j) // pref * total - pref^2 - 2*pref*j + 2*j*total - 2*j*pref - 4*j^2 // total * (pref + 2*j) - pref * (pref + 4*j) - 4*j^2 // (pref + 3 * j) * (total - pref - 3 * j) // total * (pref + 3*j) - pref * (pref + 6*j) - 9*j^2 ll ans = 0; for (int j = sum; j <= sum + (cnt - 1) * x; j += x) { ans += j * (total - j); } // cout << "! " << sum << " " << x << " " << total << " " << cnt << " => " << ans << "\n"; return ans; } ll get2(ll sum, ll x, ll total, ll cnt) { ll ans = 0; for (int j = sum + x; j <= sum + cnt * x; j += x) { ans += j * (total - j); } return ans; } int main() { ios::sync_with_stdio(0); cin.tie(0); int n, q; cin >> n >> q; for (int i = 1; i <= n; ++i) cin >> a[i]; vector<array<int, 3>> qs; vector<ll> sol(q + 1); for (int i = 1; i <= q; ++i) { int l, r; cin >> l >> r; sol[i] += (ll) (r - l + 1) * (r - l + 2) / 2; qs.push_back({l, r, i}); } sort(qs.begin(), qs.end(), [&](array<int, 3> a, array<int, 3> b) { return a[0] / K < b[0] / K || (a[0] / K == b[0] / K && a[1] < b[1]); }); int l = 1, r = 0; for (int i = 0; i < q; ++i) { int ql = qs[i][0]; int qr = qs[i][1]; int id = qs[i][2]; int total = qr - ql + 1; while (l > ql) change(a[--l], +1); while (r < qr) change(a[++r], +1); while (l < ql) change(a[l++], -1); while (r > qr) change(a[r--], -1); vector<int> big; for (auto x : s) big.push_back(x); int start = 0; { // odd positions ll pref = 0, cnt = 0; for (int j = 1; j < K; ++j) { taken[j] = 0; if (cnt % 2 == 0) { sol[id] += get(pref, j, total, (small[j] + 1) / 2); taken[j] = (small[j] + 1) / 2; cnt += (small[j] + 1) / 2; pref += ((small[j] + 1) / 2) * 1LL * j; } else { sol[id] += get(pref, j, total, small[j] / 2); taken[j] = small[j] / 2; cnt += small[j] / 2; pref += (small[j] / 2) * 1LL * j; } } for (int j = cnt % 2; j < big.size(); j += 2) { sol[id] += pref * (total - pref); pref += big[i]; } start = cnt % 2; } { // even positions ll pref = 0, cnt = 0; for (int j = 1; j < K; ++j) { sol[id] += get2(pref, j, total, small[j] - taken[j]); cnt += small[j] - taken[j]; pref += (small[j] - taken[j]) * 1LL * j; } for (int j = 1 - start; j < big.size(); j += 2) { sol[id] += pref * (total - pref); pref += big[i]; } } } for (int i = 1; i <= q; ++i) cout << sol[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...