国家集训队 小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\n",anss[i].fz,anss[i].fm);
    return 0;
}
posted @ 2019-11-14 09:18  MorsLin  阅读(103)  评论(0编辑  收藏  举报