Submission #1170609

#TimeUsernameProblemLanguageResultExecution timeMemory
1170609steveonalexDiversity (CEOI21_diversity)C++20
100 / 100
719 ms14292 KiB
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef unsigned long long ull; #define MASK(i) (1ULL << (i)) #define GETBIT(mask, i) (((mask) >> (i)) & 1) #define ALL(v) (v).begin(), (v).end() ll max(ll a, ll b){return (a > b) ? a : b;} ll min(ll a, ll b){return (a < b) ? a : b;} ll gcd(ll a, ll b){return __gcd(abs(a), abs(b));} ll lcm(ll a, ll b){return abs(a) / gcd(a, b) * abs(b);} ll LASTBIT(ll mask){return (mask) & (-mask);} int pop_cnt(ull mask){return __builtin_popcountll(mask);} int ctz(ull mask){return __builtin_ctzll(mask);} int logOf(ull mask){return 63 - __builtin_clzll(mask);} mt19937_64 rng(chrono::high_resolution_clock::now().time_since_epoch().count()); ll rngesus(ll l, ll r){return l + (ull) rng() % (r - l + 1);} double rngesus_d(double l, double r){ double cur = rngesus(0, MASK(60) - 1); cur /= MASK(60) - 1; return l + cur * (r - l); } template <class T1, class T2> bool maximize(T1 &a, T2 b){ if (a < b) {a = b; return true;} return false; } template <class T1, class T2> bool minimize(T1 &a, T2 b){ if (a > b) {a = b; return true;} return false; } template <class T> void printArr(T container, string separator = " ", string finish = "\n", ostream &out = cout){ for(auto item: container) out << item << separator; out << finish; } template <class T> void remove_dup(vector<T> &a){ sort(ALL(a)); a.resize(unique(ALL(a)) - a.begin()); } struct Query{ int l, r, idx; Query(int l = 0, int r = 0, int idx = 0): l(l), r(r), idx(idx){} }; const int N = 3e5 + 69, Q = 5e4 + 69, BLOCK = 550; int n, q; ll ans[Q]; vector<int> large_set; int cnt[N], cnt_freg[N]; void add_number(int x){ cnt_freg[cnt[x]]--; cnt_freg[++cnt[x]]++; } void del_number(int x){ cnt_freg[cnt[x]]--; cnt_freg[--cnt[x]]++; } ll continuous_sum(ll l, ll it, ll step){ return (l * 2 + (it-1) * step) * it / 2; } ll sqr_sum_simple(ll r){ return r * (r+1) * (2*r+1) / 6; } ll sqr_sum_pref(ll r, ll step){ if (r <= 0) return 0; ll dih = r / step + 1, rem = r % step; ll cur = sqr_sum_simple(dih - 1); cur *= step * step; cur += rem * rem * dih + 2 * rem * continuous_sum(0, dih, step); return cur; } ll sqr_sum(ll l, ll it, ll step){ return sqr_sum_pref(l + (it-1) * step, step) - sqr_sum_pref(l - step, step); } ll answer_query(){ vector<int> T; for(int i = 1; i < BLOCK; ++i) if (cnt_freg[i] > 0) T.push_back(i); vector<int> S; for(int i: large_set) if (cnt[i] >= BLOCK) S.push_back(cnt[i]); remove_dup(S); for(int i: S) T.push_back(i); ll ans = 0; ll n = 0; for(int i: T) n += cnt_freg[i] * i; ll l = 0, r = 0; int is_odd = 1; for(ll i: T){ ans += (i * (i+1) / 2 + i * (n-i)) * cnt_freg[i]; int to_left = 0, to_right = 0; if (is_odd){ to_left = (cnt_freg[i] + 1) / 2; to_right = cnt_freg[i] / 2; } else{ to_left = cnt_freg[i] / 2; to_right = (cnt_freg[i] + 1) / 2; } ans += (n - i) * (continuous_sum(l, to_left, i) + continuous_sum(r, to_right, i)); ans -= sqr_sum(l, to_left, i) + sqr_sum(r, to_right, i); l += to_left * i; r += to_right * i; is_odd ^= cnt_freg[i] % 2; } return ans; } void solve(){ cin >> n >> q; vector<int> a(n+1); for(int i = 1; i <= n; ++i) cin >> a[i]; map<int, int> mp; for(int i = 1; i <= n; ++i){ mp[a[i]]++; } for(auto i: mp){ if (i.second >= BLOCK) large_set.push_back(i.first); } vector<Query> queries(q); for(int i = 0; i < q; ++i){ int l, r; cin >> l >> r; queries[i] = Query(l, r, i); } sort(ALL(queries), [](Query x, Query y){ const int BLOCK = 550; if (x.l / BLOCK == y.l / BLOCK) return x.r < y.r; return x.l < y.l; }); int l = 1, r = 0; cnt_freg[0] = n; int tot = 0; for(Query i: queries){ tot += abs(l - i.l) + abs(r - i.r); while(r < i.r) { add_number(a[++r]); } while(l > i.l){ add_number(a[--l]); } while(r > i.r){ del_number(a[r--]); } while(l < i.l){ del_number(a[l++]); } ans[i.idx] = answer_query(); } for(int i = 0; i < q; ++i) cout << ans[i] << "\n"; } int main(void){ ios::sync_with_stdio(0);cin.tie(0); cout.tie(0); clock_t start = clock(); solve(); cerr << "Time elapsed: " << clock() - start << "ms!\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...