对于L,R的询问。设其中颜色为x,y,z….的袜子的个数为a,b,c。。。
那么答案即为(a*(a-1)/2+b*(b-1)/2+c*(c-1)/2….)/((R-L+1)*(R-L)/2)
化简得:(a^2+b^2+c^2+…x^2-(a+b+c+d+…..))/((R-L+1)*(R-L))
即:(a^2+b^2+c^2+…x^2-(R-L+1))/((R-L+1)*(R-L))
代码:
#include<cstdio>
#include<iostream>
#include<cmath>
#include<algorithm>
#define ll long long
using namespace std;
const int N=50010;
int n,m;
int col[N],f[N],pos[N];
ll gcd(ll x,ll y)
{
return y==0?x:gcd(y,x%y);
}
struct node
{
int id,l,r;
ll a,b;
bool operator <(const node &t)const
{
return pos[l]<pos[t.l]||(pos[l]==pos[t.l]&&r<t.r);
}
void modify()
{
ll k=gcd(a,b);
a/=k,b/=k;
}
} Q[N];
bool cmp_id(node x,node y)
{
return x.id<y.id;
}
void modify(int p,ll &ans,int add)
{
ans=ans+2*add*f[col[p]]+1;
f[col[p]]+=add;
}
void solve()
{
ll ans=0;
int l=1,r=0;
for(int i=1;i<=m;i++)
{
if(r<Q[i].r)
{
for(r=r+1;r<Q[i].r;r++) modify(r,ans,1);
modify(r,ans,1);
}
if(Q[i].l<l)
{
for(l=l-1;Q[i].l<l;l--) modify(l,ans,1);
modify(l,ans,1);
}
if(Q[i].r<r)
{
for(;Q[i].r<r;r--) modify(r,ans,-1);
}
if(Q[i].l>l)
{
for(;Q[i].l>l;l++) modify(l,ans,-1);
}
if(Q[i].l==Q[i].r)
{
Q[i].a=0;
Q[i].b=1;
continue;
}
Q[i].a=ans-(Q[i].r-Q[i].l+1),Q[i].b=(ll)(Q[i].r-Q[i].l+1)*(Q[i].r-Q[i].l);
Q[i].modify();
}
sort(Q+1,Q+1+m,cmp_id);
for(int i=1;i<=m;i++) printf("%lld/%lld\n",Q[i].a,Q[i].b);
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&col[i]);
int limit=(int)sqrt((double)n+0.5);
for(int i=1;i<=n;i++) pos[i]=(i-1)/limit+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);
solve();
}