【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;
}
posted @ 2016-01-14 17:23  sxb_201  阅读(152)  评论(0编辑  收藏  举报