Submission #1123651

#TimeUsernameProblemLanguageResultExecution timeMemory
1123651mychecksedadDiversity (CEOI21_diversity)C++17
100 / 100
478 ms39476 KiB
/* Author : Mychecksdead  */
#include<bits/stdc++.h>
using namespace std;
#define ll long long int
#define MOD (1000000000+7)
#define MOD1 (998244353)
#define pb push_back
#define all(x) x.begin(), x.end()
#define en cout << '\n'
#define ff first
#define ss second
#define pii pair<int,int>
#define vi vector<int>
const int N = 1e6+100, M = 1e5+10, K = 52, MX = 30;

inline ll hilbert(int x, int y, int pow, int rotate){
  if(pow == 0) return 0;
  int hpow = 1 << (pow-1);
  int seg = (x < hpow) ? 
  (y < hpow ? 0 : 3) : 
  (y < hpow ? 1 : 2);
  seg = (seg+rotate) & 3;
  const int rotateDelta[4] = {3, 0, 0, 1};
  int nx = x & (x^hpow), ny = y & (y^hpow);
  int nrot = (rotate+rotateDelta[seg])&3; 
  ll subSquareSize = (1ll) << (2*pow-2);
  ll ans = seg*subSquareSize;
  ll add = hilbert(nx, ny, pow-1, nrot);
  ans += (seg == 1 || seg == 2) ? add : (subSquareSize - add - 1);
  return ans;
}

int n, q, a[N], in[N];
ll ans[N], cur;
const int SS = 700;
vi V;
vector<array<ll, 4>> Q;
ll freq[N], co[N];
set<int> S;
void add(int i){
  co[freq[a[i]]]--;
  // if(co[freq[a[i]]] == 0 && freq[a[i]] > 0) S.erase(freq[a[i]]);
  freq[a[i]]++;
  co[freq[a[i]]]++;
  if(freq[a[i]] > SS && !in[a[i]]){
    in[a[i]] = 1;
    V.pb(a[i]);
  }
  // if(co[freq[a[i]]] == 1) S.insert(freq[a[i]]);
}

void rem(int i){
  co[freq[a[i]]]--;
  // if(co[freq[a[i]]] == 0 && freq[a[i]] > 0) S.erase(freq[a[i]]);
  freq[a[i]]--;
  co[freq[a[i]]]++;
  // if(co[freq[a[i]]] == 1 && freq[a[i]] > 0) S.insert(freq[a[i]]);
}

ll SQ[N], LI[N];
ll get_sq(ll x){
  return x < 0 ? 0ll : SQ[x];
  // return (x+1)*(2*x+1)*x/6;
}

ll get_li(ll x){
  return x < 0 ? 0ll : LI[x];
  // return (x*(x+1))>>1;
}

void solve(){
  cin >> n >> q;
  for(int i = 1; i <= n; ++i){
    cin >> a[i];
  }
  SQ[0] = 0;
  for(ll i = 1; i < N; ++i){
    SQ[i] = SQ[i - 1] + i * i;
    freq[i] = co[i] = 0;
    in[i] = 0;
  }
  LI[0] = 0;
  for(int i = 1; i < N; ++i){
    LI[i] = LI[i - 1] + i; 
  }
  for(int i = 1; i <= q; ++i){
    int l, r; cin >> l >> r;
    Q.pb({hilbert(l, r, 19, 0), r, l, i});
  }

  sort(all(Q));

  cur = 0;
  int L = 1, R = 0, tt = 0;
  for(auto p: Q){
    while(R < p[1]){
      ++R;
      add(R);
    }
    while(L > p[2]){
      --L;
      add(L);
    }
    while(R > p[1]){
      rem(R);
      --R;
    }
    while(L < p[2]){
      rem(L);
      ++L;
    }
    vi U, VV;
    for(int idx: V){
      if(freq[idx] <= SS){
        in[idx] = 0;
      }else{
        U.pb(freq[idx]);
        VV.pb(idx);
      }
    }
    V.swap(VV);
    sort(all(U));
    U.erase(unique(all(U)), U.end());

    cur = 0;

    ll odd = 0, even = 0, tot = 0, d = 0, TOT = R-L+1;

    for(ll pp = 1; pp <= SS; ++pp){
      if(co[pp] == 0) continue;
      ll k = co[pp];
      ll x = (k + 1) >> 1;
      ll y = k >> 1;
      if((d & 1)) swap(x, y);
      // cout << x << ' ' << y << '\n';
      ll P = (TOT - odd - pp);
      ll T = (TOT - even - pp);
      cur += x * (odd * odd + P * P);
      cur += 2 * get_li(x - 1) * pp * (odd - P);
      cur += (get_sq(y - 1) + get_sq(x - 1)) * pp * pp * 2;
      cur += y * (even * even + T * T);
      cur += 2 * get_li(y - 1) * pp * (even - T);
      // cur += get_sq(y - 1) * pp * pp * 2;

      // cur += x * P * P;
      // cur -= 2 * get_li(x - 1) * P * pp;
      // cur += get_sq(x - 1) * pp * pp;
      // cur += get_sq(y - 1) * pp * pp;

      odd += x * pp, even += y * pp;
      // else odd += y * pp, even += x * pp;

      tot += k * pp;
      d += k;
    } 
    for(ll pp: U){
      if(co[pp] == 0) continue;
      ll k = co[pp];
      ll x = (k + 1) >> 1;
      ll y = k >> 1;
      if((d & 1)) swap(x, y);
      // cout << x << ' ' << y << '\n';
      ll P = (TOT - odd - pp);
      ll T = (TOT - even - pp);
      cur += x * (odd * odd + P * P);
      cur += 2 * get_li(x - 1) * pp * (odd - P);
      cur += (get_sq(y - 1) + get_sq(x - 1)) * pp * pp * 2;
      cur += y * (even * even + T * T);
      cur += 2 * get_li(y - 1) * pp * (even - T);
      // cur += get_sq(y - 1) * pp * pp * 2;

      // cur += x * P * P;
      // cur -= 2 * get_li(x - 1) * P * pp;
      // cur += get_sq(x - 1) * pp * pp;
      // cur += get_sq(y - 1) * pp * pp;

      odd += x * pp, even += y * pp;
      // else odd += y * pp, even += x * pp;

      tot += k * pp;
      d += k;
    } 

    // cout << d << ' ' << tot << ' ' << cur << ' ' ;
    ans[p[3]] = (d * tot * (tot+1) - tot * (d-1) - cur) >> 1;

    // ++tt;
    // if(tt == SS){
    //   S.clear();
    //   for(int i = 1; i <= n; ++i){
    //     if(co[freq[i]] > 0) S.insert(freq[i]);
    //   }
    //   tt = 0;
    // }
  }


  for(int i = 1; i <= q; ++i){
    cout << ans[i] << '\n';
  }
}


int main(){
  cin.tie(0); ios::sync_with_stdio(0);
  int tt = 1, aa;
  // freopen("in.txt", "r", stdin);
  // freopen("out.txt", "w", stdout);
  while(tt--){
    solve();
    en;
  }
  cerr<<"time taken : "<<(float)clock()/CLOCKS_PER_SEC<<" seconds\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...