天天看點

BZOJ 2038: [2009國家集訓隊]小Z的襪子(hose)

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;

typedef long long ll;
const int maxn=50000+100;

inline ll gcd(ll a,ll b){
    
    return b==0?a:gcd(b,a%b);
}

ll ans;
int R[maxn],num[maxn],col[maxn];
struct Mo{
    
    int l,r;
    int id;
    ll A,B;
}mo[maxn];

inline bool cmp(Mo a,Mo b){
    
    return R[a.l]==R[b.l]?a.r<b.r:a.l<b.l;
}

inline bool CMP(Mo a,Mo b){
    
    return a.id<b.id;
}

inline void kaven(int ind,int v){
    
    ans-=(ll)num[col[ind]]*num[col[ind]];
    num[col[ind]]+=v;
    ans+=(ll)num[col[ind]]*num[col[ind]];
}

int main(){
    
    int n,m;
    scanf("%d%d",&n,&m);
    int tmp=sqrt(n);
    for(int i=1;i<=n;i++) scanf("%d",&col[i]),R[i]=i/tmp+1;
    for(int i=1;i<=m;i++){
        
        scanf("%d%d",&mo[i].l,&mo[i].r);
        mo[i].id=i;
    }
    sort(mo+1,mo+m+1,cmp);
    int l=1;
    int r=0;
    for(int i=1;i<=m;i++){
        
        while(l<mo[i].l) kaven(l,-1),l++;
        while(l>mo[i].l) kaven(l-1,1),l--;
        while(r<mo[i].r) kaven(r+1,1),r++;
        while(r>mo[i].r) kaven(r,-1),r--;
        
        if(mo[i].l==mo[i].r){
            
            mo[i].A=0;
            mo[i].B=1;
            continue;
        }
        ll tmpe=(mo[i].r-mo[i].l+1);
        mo[i].A=ans-tmpe;
        mo[i].B=tmpe*(tmpe-1);
        ll GCD=gcd(mo[i].A,mo[i].B);
        mo[i].A/=GCD;
        mo[i].B/=GCD;
    }
    sort(mo+1,mo+m+1,CMP);
    for(int i=1;i<=m;i++){
        
        printf("%lld/%lld\n",mo[i].A,mo[i].B);
    }
}