Submission #1170183

#TimeUsernameProblemLanguageResultExecution timeMemory
1170183Troll321Diversity (CEOI21_diversity)C++20
100 / 100
939 ms11128 KiB
#include <bits/stdc++.h> #define fi first #define se second #pragma GCC optimize("Ofast") #pragma GCC target("avx,avx2,fma,popcnt,bmi2,bmi,lzcnt") #pragma unroll 2 using namespace std; typedef long long ll; typedef pair<ll,ll> pll; const ll MAXN = 3e5 + 5; const ll MAXQ = 5e4 + 5; const ll MAX = 1e18; const ll BLOCK = 550; const ll MAXBLOCK = MAXN/BLOCK+5; ll n, q; ll answer[MAXQ]; ll arr[MAXN]; vector<pair<ll, pll>> blocks[MAXBLOCK]; ll oriFreq[MAXN], freq[MAXN], comp[MAXN]; vector<ll> large; vector <pll> calcv; void setVal() { calcv.clear(); for (ll val : large) { if(freq[val] < BLOCK) { comp[freq[val]]++; } } for (int i = 1; i < BLOCK; ++i) { if(comp[i]) {calcv.push_back({i, comp[i]});} } for (ll val : large) { if(freq[val] >= BLOCK) {calcv.push_back({freq[val], 1});} } sort(calcv.begin(), calcv.end()); for (ll val : large) { if(freq[val] < BLOCK) { comp[freq[val]]--; } } } ll calc(ll l, ll r) { setVal(); ll n = r-l+1; ll k = 0; ll sqSum = 0; ll bef[2] = {0,0}; ll nowpar = 1; for(auto i : calcv) { k += i.se; // i.fi (length) // i.se (banyak) for (int parity = 0; parity <= 1; ++parity) { ll len = 0; if(nowpar != parity) { len = (i.se >> 1); } else { len = ((i.se+1) >> 1); } sqSum += len*bef[parity]*bef[parity] + (len-1)*len*bef[parity]*i.fi + (len-1)*len*(2*len-1)/6*i.fi*i.fi; sqSum += len*(n*n + bef[parity]*bef[parity]) - 2*len*n*bef[parity] + len*(len+1)*i.fi*(bef[parity]-n) + len*(len+1)*(2*len+1)/6*i.fi*i.fi; bef[parity] += i.fi * len; } nowpar = ((ll)nowpar+i.se) % 2; } ll out = n*k*(n+1) - n*(k-1); out = (out - sqSum) >> 1; return out; } bool isSmall(ll val) { return oriFreq[val] < BLOCK; } void update(ll val, ll chg) { if(isSmall(val)) {comp[freq[val]]--;} freq[val] += chg; if(isSmall(val)) {comp[freq[val]]++;} } bool cmp(pair<ll,pll> a, pair<ll,pll> b) { if(a.se.se == b.se.se) {return a.se.fi < b.se.fi;} return a.se.se < b.se.se; } int main() { ios_base::sync_with_stdio(false); cin.tie(0); cin >> n >> q; for (int i = 1; i <= n; ++i) { cin >> arr[i]; oriFreq[arr[i]]++; } for (int i = 1; i <= n; ++i) { if(oriFreq[i] >= BLOCK) {large.push_back(i);} } for (int i = 1; i <= q; ++i) { pll input; cin >> input.fi >> input.se; blocks[input.fi/BLOCK].push_back({i, input}); } for (int nowBlock = 0; nowBlock*BLOCK <= n; ++nowBlock) { if(blocks[nowBlock].empty()) {continue ;} sort(blocks[nowBlock].begin(), blocks[nowBlock].end(), cmp); // Reset freq, comp memset(freq, 0, sizeof(freq)); memset(comp, 0, sizeof(comp)); ll pl = 1 + nowBlock*BLOCK, pr = pl; update(arr[pl], 1); for (int i = 0; i < blocks[nowBlock].size(); ++i) { ll ansIdx = blocks[nowBlock][i].fi; pll range = blocks[nowBlock][i].se; // Shift pl while (pl < range.fi) { update(arr[pl], -1); pl++; } while (pl > range.fi) { pl--; update(arr[pl], 1); } // Shift pr while(pr < range.se) { pr++; update(arr[pr], 1); } answer[ansIdx] = calc(range.fi, range.se); } } for (int i = 1; i <= q; ++i) { cout << answer[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...