我写了个莫队,看起来好像没什么问题,但是 WA 了。
瞪了半天没瞪出来,也没有小数据。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
int n, m;
struct que{
int l, r, id;
ll fz, fm;
}qu[100005];
int c[100005], kuai[1005], buk[100005];
ll ans;
int main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin >> n >> m;
for (int i = 1; i <= n; i++)
cin >> c[i];
for (int i = 1; i <= m; i++){
cin >> qu[i].l >> qu[i].r;
qu[i].id = i;
}
sort(qu + 1, qu + 1 + m, [](que a, que b){return a.l < b.l;});
int k1 = sqrt(m), k2 = ceil(m * 1.00 / k1) + 0.114514;
for (int i = 1; i <= k2; i++)
kuai[i] = k1 * (i - 1) + 1;
kuai[k2 + 1] = m + 1;
for (int i = 1; i <= k2; i++)
sort (qu + kuai[i], qu + kuai[i + 1], [](que a, que b){return a.r < b.r;});
for (int i = 1; i <= k2; i++){
memset(buk, 0, sizeof buk);
ans = 0;
for (int j = qu[kuai[i]].l; j <= qu[kuai[i]].r; j++)
buk[c[j]]++, ans += buk[c[j]] - 1;
ll len = qu[kuai[i]].r - qu[kuai[i]].l + 1;
ll nans = ans;
ll fm = len * (len - 1) / 2;
ll g = __gcd(fm, nans);
if (qu[kuai[i]].l != qu[kuai[i]].r){
qu[kuai[i]].fz = nans / g;
qu[kuai[i]].fm = fm / g;
}else{
qu[kuai[i]].fz = 0;
qu[kuai[i]].fm = 1;
}
for (int ii = kuai[i] + 1; ii < kuai[i + 1]; ii++){
for (int j = qu[ii - 1].r + 1; j <= qu[ii].r; j++)
buk[c[j]]++, ans += buk[c[j]] - 1;
if (qu[ii].l > qu[ii - 1].l){
for (int j = qu[ii - 1].l; j < qu[ii].l; j++)
buk[c[j]]--, ans += buk[c[j]];
}else{
for (int j = qu[ii].l; j < qu[ii - 1].l; j++)
buk[c[j]]++, ans += buk[c[j]] - 1;
}
ll len = qu[ii].r - qu[ii].l + 1;
ll nans = ans;
ll fm = len * (len - 1) / 2;
ll g = __gcd(fm, nans);
if (qu[ii].l != qu[ii].r){
qu[ii].fz = nans / g;
qu[ii].fm = fm / g;
}else{
qu[ii].fz = 0;
qu[ii].fm = 1;
}
}
}
sort (qu + 1, qu + 1 + m, [](que a, que b){return a.id < b.id;});
for (int i = 1; i <= m; i++)
cout << qu[i].fz << "/" << qu[i].fm << "\n";
}