這是一篇不帶修改的莫隊
原來莫隊是利用分塊的思想最佳化一個路徑(曼哈頓距離)-- 幾何解釋
int n, m, a[N];
struct Q{
int l, r, id;
}q[N];
int pos[N], cnt[N], ans[N];
ll ANS;
bool mo_cmp(Q x, Q y){
if(pos[x.l] != pos[y.l]){
return pos[x.l] < pos[y.l];
}
if(pos[x.l] & 1) return x.r > y.r; // 奇偶性最佳化
else return x.r < y.r;
}
void add(int x){
ANS -= cnt[a[x]]*cnt[a[x]];
cnt[a[x]]++;
ANS += cnt[a[x]]*cnt[a[x]];
}
void del(int x){
ANS -= cnt[a[x]]*cnt[a[x]];
cnt[a[x]]--;
ANS += cnt[a[x]]*cnt[a[x]];
}
inline int read()
{
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-')
f=-1;
ch=getchar();
}
while(ch>='0' && ch<='9')
x=x*10+ch-'0',ch=getchar();
return x*f;
}
void write(int x)
{
if(x<0)
putchar('-'),x=-x;
if(x>9)
write(x/10);
putchar(x%10+'0');
return;
}
void solve() {
int k;
n = read(); m = read(); k = read();
int block = sqrt(n);
for(int i = 1; i <= n; i++){
a[i] = read();
pos[i] = (i - 1)/block + 1;
}
for(int i = 1; i <= m; i++){
q[i].l = read();
q[i].r = read();
q[i].id = i;
}
sort(q + 1, q + 1 + m, mo_cmp);
int L = 1, R = 0;
for(int i = 1; i <= m; i++){
while(L < q[i].l) del(L), L++;
while(L > q[i].l) L--, add(L);
while(R < q[i].r) R++, add(R);
while(R > q[i].r) del(R), R--;
ans[q[i].id] = ANS;
}
for(int i = 1; i <= m; i++) write(ans[i]), putchar('\n');
}