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

传送门
莫队算法入门题
这里莫队讲得非常好。
每个询问的的答案 分母:区间长度 × × (区间长度 1 − 1 ),分子:区间内每种颜色出现次数 × × (出现次数 1 − 1 )。
l l 同块,以r为关键字否则以 l l <script type="math/tex" id="MathJax-Element-222">l</script>为关键字排序。

#include<bits/stdc++.h>
#define il inline
#define ll long long
using namespace std;
const int N=5e5+5;
#define getchar()(p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[1<<21],*p1=buf,*p2=buf;
il int read(){
    int x=0,f=1;char c=getchar();
    for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
    for(;isdigit(c);c=getchar()) x=(x+(x<<2)<<1)+c-48;
    return x*f;
}
char sr[1<<21],z[20];int C=-1,Z;
il void Ot(){fwrite(sr,1,C+1,stdout),C=-1;}
il void print(ll x,char cc){
    if(C>1<<20)Ot();if(x<0)sr[++C]=45,x=-x;
    while(z[++Z]=x%10+48,x/=10);
    while(sr[++C]=z[Z],--Z);sr[++C]=cc;
}
struct nd{int l,r,id;ll A,B;}q[N];
int n,m,s,a[N],bl[N];ll sum[N],ans;
bool cmp1(nd a,nd b){return bl[a.l]==bl[b.l]?a.r<b.r:a.l<b.l;}
bool cmp2(nd a,nd b){return a.id<b.id;};
il ll sqr(ll x){return x*x;} 
il void del(int x){ans-=sqr(sum[a[x]]--),ans+=sqr(sum[a[x]]);}
il void ins(int x){ans-=sqr(sum[a[x]]++),ans+=sqr(sum[a[x]]);}
il ll gcd(ll a,ll b){while(b^=a^=b^=a%=b);return a;}
int main(){
    n=read(),m=read(),s=sqrt(n);
    for(int i=1;i<=n;++i) a[i]=read(),bl[i]=(i-1)/s+1;
    for(int i=1;i<=m;++i) q[i].l=read(),q[i].r=read(),q[i].id=i;
    sort(q+1,q+m+1,cmp1);
    for(int i=1,l=1,r=0;i<=m;++i){
        while(l<q[i].l) del(l++);
        while(l>q[i].l) ins(--l);
        while(r<q[i].r) ins(++r);
        while(r>q[i].r) del(r--);
        if(q[i].l==q[i].r){q[i].A=0;q[i].B=1;continue;}
        q[i].A=ans-(q[i].r-q[i].l+1);
        q[i].B=1ll*(q[i].r-q[i].l+1)*(q[i].r-q[i].l);
        ll g=gcd(q[i].A,q[i].B);q[i].A/=g,q[i].B/=g;
    }
    sort(q+1,q+m+1,cmp2);
    for(int i=1;i<=m;++i) print(q[i].A,'/'),print(q[i].B,'\n');
    Ot();return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值