【bzoj 2038】小Z的袜子(莫队算法)

传送门biu~
莫队裸题,是莫涛在论文中提到的经典题目。【莫队(带修改)模板点这里】
用莫队维护在区间[l,r]中选择相同颜色的袜子的方案数。对于每个询问,分子为莫队中维护的方案数,分母为在区间[l,r]中选择两只袜子共有多少种选择方案。

#include<bits/stdc++.h>
using namespace std;
int n,m;
long long ans;
int a[50005],sum[50005],block[50005];
struct Ques{int l,r,id;long long a,b;}q[50005];
bool cmp1(Ques a,Ques b){return block[a.l]<block[b.l] || block[a.l]==block[b.l] && a.r<b.r;}
bool cmp2(Ques a,Ques b){return a.id<b.id;}
inline void update(int x,int opt){
    ans-=1ll*sum[a[x]]*(sum[a[x]]-1);
    sum[a[x]]+=opt;
    ans+=1ll*sum[a[x]]*(sum[a[x]]-1);
}
int main(){
    scanf("%d%d",&n,&m);
    int blocksiz=sqrt(n);
    for(int i=1;i<=n;++i){
        scanf("%d",&a[i]);
        block[i]=(i-1)/blocksiz+1;
    }
    for(int i=1;i<=m;++i)   scanf("%d%d",&q[i].l,&q[i].r),q[i].id=i;
    sort(q+1,q+m+1,cmp1);
    int L=1,R=0;
    for(int i=1;i<=m;++i){
        while(R<q[i].r) update(++R,1);
        while(R>q[i].r) update(R--,-1);
        while(L>q[i].l) update(--L,1);
        while(L<q[i].l) update(L++,-1);
        q[i].a=ans;q[i].b=1ll*(q[i].r-q[i].l+1)*(q[i].r-q[i].l);
        long long 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)   printf("%lld/%lld\n",q[i].a,q[i].b);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zP1nG

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值