#include <cstdio>
#include <algorithm>
#include <cmath>
#define MAXN 500000
#define int long long
using namespace std;
int a[MAXN + 10], cnt[MAXN + 10], sum[MAXN + 10], ans1[MAXN + 10], ans2[MAXN + 10];
struct node {
int l, r, cl, ind;
}in[MAXN + 10];
int ans = 0;
bool cmp(node &x, node &y) {
return ((x.cl != y.cl) ? (x.l < y.l) : ((x.cl & 1) ? (x.r < y.r) : (x.r > y.r)));
}
void del(int p) {
ans -= (cnt[a[p]]) * (cnt[a[p]]);
cnt[a[p]] --;
ans += (cnt[a[p]]) * (cnt[a[p]]);
}
void add(int p) {
ans -= (cnt[a[p]]) * (cnt[a[p]]);
cnt[a[p]] ++;
ans += (cnt[a[p]]) * (cnt[a[p]]);
}
int gcd(int n, int m) {
return ((!m) ? (n) : (gcd(m, n % m)));
}
signed main() {
int n, m, len;
len = sqrt(n);
scanf("%lld%lld", &n, &m);
for(int p = 1; p <= n; p++)
scanf("%lld", &a[p]);
for(int p = 1; p <= m; p++) {
scanf("%lld%lld", &in[p].l, &in[p].r);
in[p].cl = (in[p].l) - 1 / len;
in[p].ind = p;
}
sort(in + 1, in + m + 1, cmp);
int l = 1, r = 0;
for(int p = 1; p <= m; p++) {
while(l < in[p].l) del(l++);
while(l > in[p].l) add(--l);
while(r < in[p].r) add(++r);
while(r > in[p].r) del(r--);
int len = in[p].r - in[p].l + 1;
if(in[p].l == in[p].r) {
ans1[in[p].ind] = 0, ans2[in[p].ind] = 1;
continue;
}
int G = gcd(ans - len, len * (len - 1));
ans1[in[p].ind] = (ans - len) / G;
ans2[in[p].ind] = len * (len - 1) / G;
}
for(int p = 1; p <= m; p++)
printf("%lld/%lld\n", ans1[p], ans2[p]);
}
不对啊不对啊我明明用了奇偶块排序啊/yiw
难道是卡 define int long long?