【BZOJ 2038】 [2009国家集训队]小Z的袜子(hose)
太神了!!
long long
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <cmath>
#define MAXN 1000000
#define INF 1000000000
#define MO 233333333
#define LL long long
using namespace std;
struct P
{
int L,R;
int id;
}team[50000+1];
LL a[50000+1];
LL num[50000+1];
LL ans[50000+1][2];
LL n,m;
LL cnt;
bool cmp(P a,P b)
{
if(a.L/cnt==b.L/cnt) return a.R<b.R;
return a.L<b.L;
}
LL Gcd(LL x,LL y)
{
if(y==0) return x;
return Gcd(y,x%y);
}
int main()
{
cin>>n>>m;
for(LL i=1;i<=n;i++) scanf("%d",&a[i]);
for(LL i=1;i<=m;i++) scanf("%d %d",&team[i].L,&team[i].R),team[i].id=i;
cnt=sqrt(m);
sort(team+1,team+m+1,cmp);
LL L=1,R=1;num[a[1]]=1;
LL ANS=1;
for(LL i=1;i<=m;i++)
{
// cout<<team[i].L<<' '<<team[i].R<<endl;
while(L<team[i].L)
{
ANS-=num[a[L]]*num[a[L]];
num[a[L]]--;
ANS+=num[a[L]]*num[a[L]];
L++;
}
while(L>team[i].L)
{
L--;
ANS-=num[a[L]]*num[a[L]];
num[a[L]]++;
ANS+=num[a[L]]*num[a[L]];
}
while(R<team[i].R)
{
R++;
ANS-=num[a[R]]*num[a[R]];
num[a[R]]++;
ANS+=num[a[R]]*num[a[R]];
}
while(R>team[i].R)
{
ANS-=num[a[R]]*num[a[R]];
num[a[R]]--;
ANS+=num[a[R]]*num[a[R]];
R--;
}
ans[team[i].id][0]=ANS-(R-L+1);
ans[team[i].id][1]=(R-L+1)*(R-L+1-1);
LL tmp=Gcd(ans[team[i].id][0],ans[team[i].id][1]);
ans[team[i].id][0]/=tmp;
ans[team[i].id][1]/=tmp;
if(ans[team[i].id][0]==0) ans[team[i].id][1]=1;
// cout<<'*'<<' '<<ans[team[i].id][0]<<' '<<ans[team[i].id][1]<<endl;
}
for(LL i=1;i<=m;i++) printf("%lld/%lld\n",ans[i][0],ans[i][1]);
return 0;
}