国家集训队 小Z的袜子

Posted wxl-ezio

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了国家集训队 小Z的袜子相关的知识,希望对你有一定的参考价值。

传送门


自从“HH的项链”被树状数组干爆了之后,莫队终于扬眉吐气了一把。


很经典的莫队模板题,好像没什么好说的……

代码有(十)些(分)冗长,将就着看吧……

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define LL long long
using namespace std;
struct zzz{
    LL l,r,pos;
}que[50010]; int n,m,sq;
bool cmp(zzz x,zzz y){
    if(x.l/sq != y.l/sq) return x.l/sq < y.l/sq;
    else return x.r < y.r;
}
LL read(){
    LL k=0; char c=getchar();
    for(;c<'0'||c>'9';) c=getchar();
    for(;c>='0'&&c<='9';c=getchar())
      k=(k<<3)+(k<<1)+c-48;
    return k;
}
LL a[50010],tong[50010];
struct hhh{
    LL fm,fz;
}anss[50010];
LL gcd(LL x,LL y){
    return x%y==0? y:gcd(y,x%y);
}
int main(){
    n=read(),m=read(); sq=sqrt(n);
    for(int i=1;i<=n;i++) a[i]=read();
    for(int i=1;i<=m;i++)
      que[i].l=read(),que[i].r=read(), que[i].pos=i;
    sort(que+1,que+m+1,cmp);
    LL l=1,r=0,ans=0;
    for(int i=1;i<=m;i++){
        while(l<que[i].l){
            if(tong[a[l]]>0)
              ans-=tong[a[l]]*tong[a[l]];
            tong[a[l++]]--;
            if(tong[a[l-1]]>0)
              ans+=tong[a[l-1]]*tong[a[l-1]];
        }
        while(l>que[i].l){
            if(tong[a[l-1]]>0)
              ans-=tong[a[l-1]]*tong[a[l-1]];
            tong[a[--l]]++;
            if(tong[a[l]]>0)
              ans+=tong[a[l]]*tong[a[l]];
        }
        while(r<que[i].r){
            if(tong[a[r+1]]>0)
              ans-=tong[a[r+1]]*tong[a[r+1]];
            tong[a[++r]]++;
            if(tong[a[r]]>0)
              ans+=tong[a[r]]*tong[a[r]];
        }
        while(r>que[i].r){
            if(tong[a[r]]>0)
              ans-=tong[a[r]]*tong[a[r]];
            tong[a[r--]]--;
            if(tong[a[r-1]]>0)
              ans+=tong[a[r+1]]*tong[a[r+1]];
        }
        if(l==r||ans==r-l+1){
            anss[que[i].pos].fz=0; anss[que[i].pos].fm=1;
            continue;
        }
        LL g=gcd(ans-(r-l+1),(r-l+1)*(r-l));
        anss[que[i].pos].fz=(ans-(r-l+1))/g;
        anss[que[i].pos].fm=((r-l+1)*(r-l))/g;
    }
    for(int i=1;i<=m;i++)
      printf("%lld/%lld
",anss[i].fz,anss[i].fm);
    return 0;
}

以上是关于国家集训队 小Z的袜子的主要内容,如果未能解决你的问题,请参考以下文章

2038: [2009国家集训队]小Z的袜子(hose)

[国家集训队]小Z的袜子(莫队,概率)

P1494 [国家集训队]小Z的袜子(莫队)

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

国家集训队 小Z的袜子

BZOJ2038 [2009国家集训队]小Z的袜子(hose)