题链:https://www.luogu.com.cn/problem/P1494
思路:考虑加入一只袜子,对于分子,假设之前有相同的k个袜子,那么方案数为k*(k-1)/2,现在变为k+1,方案数为k*(k+1)/2,增加了2*k/2;分母也类似,假设现在总共有n个袜子,那么方案数为n*(n-1)/2,现在变为n+1,方案数为n*(n+1)/2,增加了2*n/2。分子、分母都除了2,相当于不除。删除是也类似。
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N = 5e4+10;
int n,m,a[N];
struct node{
int l,r,id;
}q[N];
int base,belong[N];
ll up=0,down=0,ans1[N],ans2[N],g;
bool cmp(node a,node b){
return (belong[a.l]^belong[b.l])?belong[a.l]<belong[b.l]:((belong[a.l]&1)?a.r<b.r:a.r>b.r);
}
int num[N],cnt=0;
void add(int x){
up+=(num[a[x]]<<1);
down+=(cnt<<1);
++num[a[x]];
++cnt;
}
void del(int x){
--num[a[x]];
--cnt;
up-=(num[a[x]]<<1);
down-=(cnt<<1);
}
int main(void){
scanf("%d%d",&n,&m);
base=ceil(sqrt(1.0*n));
for(int i=1;i<=n;i++)
scanf("%d",&a[i]),belong[i]=i/base;
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,cmp);
int l=1,r=0;
for(int i=1;i<=m;i++){
int ql=q[i].l,qr=q[i].r;
while(l<ql) del(l++);
while(l>ql) add(--l);
while(r<qr) add(++r);
while(r>qr) del(r--);
if(!up) ans2[q[i].id]=1;
else{
g=__gcd(up,down);
ans1[q[i].id]=up/g;
ans2[q[i].id]=down/g;
}
}
for(int i=1;i<=m;i++)
printf("%lld/%lld\n",ans1[i],ans2[i]);
return 0;
}