luogu1494 [国家集训队]小Z的袜子

#include <algorithm>
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
int n, m, a[50005], blc, bel[50005], cnt[50005];
long long ansfz[50005], ansfm[50005], ans;
struct Node{
    int l, r, id;
}nd[50005];
bool cmp(Node x, Node y){
    if(bel[x.l]!=bel[y.l])	return bel[x.l]<bel[y.l];
    if(bel[x.l]&1)	return x.r<y.r;
    else	return x.r>y.r;
}
void add(int x){
    cnt[a[x]]++;
    if(cnt[a[x]]>1)	ans += cnt[a[x]]*(cnt[a[x]]-1) - (cnt[a[x]]-2)*(cnt[a[x]]-1);
}
void del(int x){
    cnt[a[x]]--;
    if(cnt[a[x]]>0)	ans += cnt[a[x]]*(cnt[a[x]]-1) - (cnt[a[x]]+1)*cnt[a[x]];
}
//注意:以上add和del中的限制条件要么同时加要么同时不加。
//因为cnt可能是负值。比如说在[4,4]到[7,7]的过程中
long long gcd(long long a, long long b){
    return b==0?a:gcd(b,a%b);
}
int main(){
    cin>>n>>m;
    blc = sqrt(n);
    for(int i=1; i<=n; i++){
        scanf("%d", &a[i]);
        bel[i] = (i - 1) / blc + 1;
    }
    for(int i=1; i<=m; i++){
        scanf("%d %d", &nd[i].l, &nd[i].r);
        nd[i].id = i;
    }
    sort(nd+1, nd+1+m, cmp);
    int ll=nd[1].l, rr=nd[1].r;
    for(int i=ll; i<=rr; i++)	add(i);
    if(!ans)	ansfz[nd[1].id] = 0, ansfm[nd[1].id] = 1;
    else{
        long long qwq=gcd(ans, (long long)(rr-ll+1)*(rr-ll));
        ansfz[nd[1].id] = ans / qwq;
        ansfm[nd[1].id] = (long long)(rr - ll + 1) * (rr - ll) / qwq;
    }
    for(int i=2; i<=m; i++){
        while(ll<nd[i].l)	del(ll++);
        while(ll>nd[i].l)	add(--ll);
        while(rr<nd[i].r)	add(++rr);
        while(rr>nd[i].r)	del(rr--);
        if(!ans)	ansfz[nd[i].id] = 0, ansfm[nd[i].id] = 1;
        else{
            long long qwq=gcd(ans, (long long)(rr-ll+1)*(rr-ll));
            ansfz[nd[i].id] = ans / qwq;
            ansfm[nd[i].id] = (long long)(rr - ll + 1) * (rr - ll) / qwq;
        }
    }
    for(int i=1; i<=m; i++)
        printf("%lld/%lld
", ansfz[i], ansfm[i]);
    return 0;
}

原文地址:https://www.cnblogs.com/poorpool/p/8489064.html