BZOJ 2038 小Z的襪子 莫隊
阿新 • • 發佈:2019-01-09
注意一些量的初始化,sum ,L,R,UP 這類的
注意區間先擴後增
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn=50005;
int c[maxn];
LL num[maxn];
int n,m;
LL ans1[maxn],ans2[maxn];
struct node{
int l,r,id;
}Q[maxn];
int pos[maxn];
bool cmp(node a,node b){
if(pos[a.l]==pos[b.l])return a.r<b.r;
return pos[a.l]<pos[b.l];
}
LL gcd(LL a,LL b){
return b==0?a:gcd(b,a%b);
}
int L,R;
LL UP,DOWN,sum;
LL C(LL x){
return x*(x-1)/2;
}
void add(int x){
if(num[c[x]]){
UP+=C(num[c[x]]+1)-C(num[c[x]]);
}
num[c[x]]++;
sum++;
}
void del(int x){
if(num[c[x]]>=2 ){
UP-=C(num[c[x]])-C(num[c[x]]-1);
}
num[c[x]]--;
sum--;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&c[i]);
}
int sz=sqrt(n);
for(int i=1;i<=m;i++){
scanf("%d%d",&Q[i].l,&Q[i].r);
Q[i].id=i;
pos[i]=i/sz;
}
L=1 ,R=1,UP=0,sum=1;
memset(num,0,sizeof(num));
num[c[1]]=1;
sort(Q+1,Q+1+m,cmp);
for(int i=1;i<=m;i++){
while(R<Q[i].r){
R++;
add(R);
}
while(L>Q[i].l){
L--;
add(L);
}
while(R>Q[i].r){
del(R);
R--;
}
while(L<Q[i].l){
del(L);
L++;
}
DOWN=C(sum);
if(UP==0){
ans1[Q[i].id]=0;
ans2[Q[i].id]=1;
continue;
}
LL d=gcd(UP,DOWN);
ans1[Q[i].id]=UP/d;;
ans2[Q[i].id]=DOWN/d;
}
for(int i=1;i<=m;i++){
printf("%lld/%lld\n",ans1[i],ans2[i]);
}
return 0;
}