【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;
}

你可能感兴趣的:(【BZOJ 2038】 [2009国家集训队]小Z的袜子(hose))