제출 #492961

#제출 시각아이디문제언어결과실행 시간메모리
492961blueDiversity (CEOI21_diversity)C++17
4 / 100
3 ms6988 KiB
#include <iostream> #include <vector> #include <algorithm> #include <cassert> #include <deque> using namespace std; const int mx = 300'000; const int mxQ = 50'000; const int rt = 500; using ll = long long; using vi = vector<int>; using vll = vector<ll>; #define sz(x) (int(x.size())) int N, Q; vi a(1+mx); vi l(1+mxQ), r(1+mxQ); vll ans(1+mxQ); int L = 1; int R = 0; vll ct(1+mx, 0); vll freq(1+mx, 0); vector<ll> sizes; vector<bool> occ(1+mx, 0); const ll bs = 1'000'000'000; const int bc = 4; struct largeint { vll x = vll(bc, 0); largeint() { ; } largeint(ll k) { for(int u = 0; u < bc; u++) { x[u] += k%bs; k /= bs; } } ll get_long() { return x[0] + bs*x[1] + bs*bs*x[2]; } }; largeint operator + (largeint X, largeint Y) { largeint res; for(int u = 0; u < bc; u++) { res.x[u] = X.x[u] + Y.x[u]; if(u+1 < bc) { res.x[u+1] += res.x[u] / bs; res.x[u] %= bs; } } return res; } largeint operator - (largeint X, largeint Y) { largeint res; for(int u = 0; u < bc; u++) { res.x[u] = X.x[u] - Y.x[u]; if(res.x[u] < 0) { res.x[u] += bs; res.x[u+1] -= 1; } } return res; } largeint operator * (largeint X, largeint Y) { largeint res; for(int u = 0; u < bc; u++) { for(int v = 0; v < bc; v++) { if(u+v >= bc) continue; res.x[u+v] += X.x[u] * Y.x[v]; if(res.x[u+v] >= bs) { res.x[u+v+1] += res.x[u+v]/bs; res.x[u+v] %= bs; } } } for(int u = 0; u+1 < bc; u++) { if(u+1 < bc) { res.x[u+1] += res.x[u] / bs; res.x[u] %= bs; } } return res; // for(int u = 0; u < bc; u++) // { // res.x[u] = X.x[u] + Y.x[u]; // if(u+1 < bc) // { // res.x[u+1] += res.x[u] / bs; // res.x[u] %= bs; // } // } } largeint ap_sum(ll a, ll d, ll n) { return largeint((n * (2*a + (n-1)*d))/2); } largeint ap_sq_sum(ll a, ll d, ll n) { /* a^2 + (a+d)^2 + ... + (a+(n-1)*d)^2 = n * a^2 + 2*a*(0d + 1d + ... + (n-1)d) + 0d^2 + d^2 + ... (n-1)d ^ 2 = n*a^2 + 2*a*d * (n-1)*n/2 + d^2 * (n-1)*(n)*(2n-1)/6 */ // assert(d*n <= 300'000); // assert(d*d*n*n*2*n <= 1'000'000'000'000'0000); return largeint(n*a*a + a*d*(n-1)*n) + largeint(d*d)*largeint(((n-1)*n*(2*n-1))/6LL); } ll get_ans() { vector<ll> sizes2; for(ll s: sizes) { if(occ[s]) continue; if(freq[s] == 0) continue; sizes2.push_back(s); occ[s] = 1; } sizes = sizes2; sizes2.clear(); for(ll s: sizes) occ[s] = 0; sort(sizes.begin(), sizes.end(), [] (int u, int v) { return u > v; }); deque< pair<ll, ll> > ord; int z = 0; for(ll s: sizes) { if(freq[s] % 2 == 1) { if(z) ord.push_back({s, 1}); else ord.push_front({s, 1}); z = !z; } if(freq[s]/2) { ord.push_back({s, freq[s]/2}); ord.push_front({s, freq[s]/2}); } } ord.push_front({0, 0}); largeint ans(0); ll tot = 0; int P = sz(ord); vll prefsum(1+P, 0); for(int i = 1; i <= P; i++) { prefsum[i] = prefsum[i-1] + (ord[i].first * ord[i].second); } tot = prefsum[P]; for(int i = 1; i <= P; i++) { ans = ans + largeint(ord[i].second) * largeint((ord[i].first * (ord[i].first + 1))/2); ans = ans + largeint(ord[i].second * largeint(largeint(ord[i].first) * (largeint(tot) - largeint(ord[i].first)))); ans = ans + largeint((tot - ord[i].first) * ap_sum(prefsum[i-1], ord[i].first, ord[i].second)); ans = ans - ap_sq_sum(prefsum[i-1], ord[i].first, ord[i].second); } return ans.get_long(); } void add_species(int a) { freq[ct[a]]--; ct[a]++; freq[ct[a]]++; sizes.push_back(ct[a]); } void remove_species(int a) { freq[ct[a]]--; ct[a]--; freq[ct[a]]++; sizes.push_back(ct[a]); } void expand_right() { R++; add_species(a[R]); } void expand_left() { L--; add_species(a[L]); } void contract_right() { remove_species(a[R]); R--; } void contract_left() { remove_species(a[L]); L++; } int main() { cin >> N >> Q; for(int i = 1; i <= N; i++) cin >> a[i]; for(int j = 1; j <= Q; j++) cin >> l[j] >> r[j]; vi I(Q); for(int j = 0; j < Q; j++) I[j] = j+1; sort(I.begin(), I.end(), [] (int u, int v) { if(l[u]/rt != l[v]/rt) return l[u]/rt < l[v]/rt; else return r[u] < r[v]; }); freq[0] = mx; for(int q: I) { while(R < r[q]) expand_right(); while(L > l[q]) expand_left(); while(R > r[q]) contract_right(); while(L < l[q]) contract_left(); ans[q] = get_ans(); } for(int q = 1; q <= Q; q++) cout << ans[q] << '\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...