This submission is migrated from previous version of oj.uz, which used different machine for grading. This submission may have different result if resubmitted.
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define fi first
#define se second
#define pb push_back
typedef pair<int, int> ii;
typedef pair<ii, int> iii;
typedef pair<ii, ii> iiii;
const int N = 4e5 + 5;
const int oo = 1e18 + 7, mod = 1e9 + 7;
int n, q, a[N];
int cnt[N];
int cntt[N];
int S = 500;
bool cmp(iii a, iii b){
if(a.fi.fi / S != b.fi.fi / S) return (a.fi.fi / S < b.fi.fi / S);
else{
if(!((a.fi.fi / S) & 1)) return (a.fi.se < b.fi.se);
else return (a.fi.se > b.fi.se);
}
}
vector<iii> queries;
vector<int> big;
set<int> se;
void ins(int pos){
cntt[cnt[a[pos]]]--;
cnt[a[pos]]++;
//cout << a[pos] << " " << cnt[a[pos]] << "\n";
cntt[cnt[a[pos]]]++;
}
void er(int pos){
cntt[cnt[a[pos]]]--;
cnt[a[pos]]--;
//cout << a[pos] << " " << cnt[a[pos]] << "\n";
cntt[cnt[a[pos]]]++;
}
int answer[N];
void process(){
cin >> n >> q;
for(int i = 1; i <= n; i++){
cin >> a[i];
cnt[a[i]]++;
//cnt[a[i]].fi++;
}
for(int i = 1; i <= 300000; i++) if(cnt[i] >= S) big.pb(i);
for(int i = 1; i <= 300000; i++) cnt[i] = 0;
for(int i = 1; i <= q; i++){
int l, r;
cin >> l >> r;
queries.pb({{l, r}, i});
}
sort(queries.begin(), queries.end(), cmp);
int lstl = 0, lstr = 0;
bool ck = 1;
for(int i = 0; i < q; i++){
//sort(cnt + 1, cnt + 300000 + 1, greater<ii>());
while(lstr < queries[i].fi.se){
//ins(a[lstr]);
lstr++;
ins(lstr);
}
while(lstl > queries[i].fi.fi){
lstl--;
ins(lstl);
}
while(lstl < queries[i].fi.fi){
if(lstl) er(lstl);
lstl++;
}
while(lstr > queries[i].fi.se){
er(lstr);
lstr--;
}
if(!ck) continue;
//cout << lstl << " " << lstr << "\n";
vector<ii> vc1, vc2;
int total = 0;
for(int it = 1; it < S; it++){
if(!cntt[it]) continue;
int temp1 = (cntt[it] + 1) / 2, temp2 = cntt[it] / 2;
if(!(total & 1)){
if(temp1) vc1.pb({it, temp1});
if(temp2) vc2.pb({it, temp2});
}
else{
if(temp2) vc1.pb({it, temp2});
if(temp1) vc2.pb({it, temp1});
}
total += cntt[it];
}
set<int> uos;
for(auto it : big){
if(cnt[it] < S) continue;
//if(uos.find(cnt[it]) != uos.end()) continue;
uos.insert(cnt[it]);
}
for(auto it : uos){
int temp1 = (cntt[it] + 1) / 2, temp2 = cntt[it] / 2;
if(!(total & 1)){
if(temp1) vc1.pb({it, temp1});
if(temp2) vc2.pb({it, temp2});
}
else{
if(temp2) vc1.pb({it, temp2});
if(temp1) vc2.pb({it, temp1});
}
total += cntt[it];
}
//sort(vc1.begin(), vc1.end()), sort(vc2.begin(), vc2.end());
//for(int j = 1; j <= 5; j++) cout << j << " " << cnt[j] << "\n";
for(int j = vc2.size() - 1; j >= 0; j--) vc1.pb(vc2[j]);
//for(auto it : vc1) if(lstl == 1 && lstr == 8) cout << it.fi << " " << it.se << "\n";
int tol = 0, tol2 = 0, toll = 1;
for(auto it : vc1){
//cout << lstl << " " << lstr << " " << it.fi << " " << it.se << "\n";
int temp = ((it.se * (it.se + 1) * (2 * it.se + 1)) / 6 + (it.se * (it.se + 1)) / 2) / 2 - it.se;
temp = temp * it.fi * it.fi + toll * it.fi * it.se;
temp += it.se * (it.fi * (it.fi - 1) / 2);
temp += tol * ((it.se * (it.se - 1)) / 2) * it.fi;
toll += ((it.se * (it.se + 1)) / 2) * it.fi + tol * (it.se - 1);
tol += it.fi * it.se;
toll += tol;
tol2 += temp;
}
answer[queries[i].se] = tol2;
//if(!(i % 1000) && (long double)clock() / (long double)CLOCKS_PER_SEC >= 3.0) ck = 0;
}
for(int i = 1; i <= q; i++) cout << answer[i] << "\n";
}
signed main(){
ios_base::sync_with_stdio(0);
//freopen("diverse.inp", "r", stdin);
//freopen("diverse.out", "w", stdout);
process();
}
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |
# | Verdict | Execution time | Memory | Grader output |
---|
Fetching results... |