现在看来还是蛮简单的(手动滑稽)。。。。。。。。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#define maxn 50020
#define LL long long
using namespace std;
int n,m,col[maxn],bl[maxn],block;
LL ans,sum[maxn],ans1[maxn],ans2[maxn];
LL gcd(LL a,LL b){return !b ? a : gcd(b,a%b);}
struct question{
int l,r,id;
bool operator<(const question& y)const{
return bl[l]==bl[y.l] ? r<y.r : l<y.l;
}
}q[maxn];
void update(int x,int add){
ans-=(sum[x]*(sum[x]-1)/2);
sum[x]+=add;
ans+=sum[x]*(sum[x]-1)/2;
}
void up(int id,int l,int r){
LL all=((LL)r-l+1)*(r-l)/2;
LL g=gcd(ans,all);
if(ans==0)ans1[id]=0,ans2[id]=1;
else ans1[id]=ans/g,ans2[id]=all/g;
}
int main(){
scanf("%d%d",&n,&m);block=sqrt(n);
for(int i=1;i<=n;i++)scanf("%d",col+i),bl[i]=(i-1)/block+1;
for(int i=1;i<=m;i++){
scanf("%d%d",&q[i].l,&q[i].r);q[i].id=i;
}sort(q+1,q+1+m);
int l=1,r=0;
for(int a,b,i=1;i<=m;i++){
a=q[i].l,b=q[i].r;
while(l<a)update(col[l++],-1);
while(l>a)update(col[--l],1);
while(r<b)update(col[++r],1);
while(r>b)update(col[r--],-1);
up(q[i].id,l,r);
}
for(int i=1;i<=m;i++)printf("%lld/%lld\n",ans1[i],ans2[i]);
return 0;
}