BZOJ 2038 莫队

题目链接


入门题

存个模板


#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;

const int A = 1e5 + 10;
ll sum[A],Ans_1[A],Ans_2[A],res;
int belong[A],a[A],n,m;
class Que{
public:
    int l,r,id;
    bool operator<(const Que& rhs)const{
        if(belong[l] == belong[rhs.l]) return belong[r] < belong[rhs.r];
        return belong[l] < belong[rhs.l];
    }
}Q[A];

ll gcd(ll a,ll b){
    if(b == 0) return a;
    return gcd(b,a%b);
}

void update(int pos,int v){
    res -= sum[a[pos]]*sum[a[pos]];
    sum[a[pos]] += v;
    res += sum[a[pos]]*sum[a[pos]];
}

void solve(){
    res = 0;
    int L = 1,R = 0;
    for(int i=1 ;i<=m ;i++){
        int id = Q[i].id;
        while(R < Q[i].r) update(++R,1);
        while(L > Q[i].l) update(--L,1);
        while(R > Q[i].r) update(R--,-1);
        while(L < Q[i].l) update(L++,-1);
        if(Q[i].l == Q[i].r){
            Ans_1[i] = 0;
            Ans_2[i] = 1;
            continue;
        }
        ll len = Q[i].r - Q[i].l + 1;
        Ans_1[id] = res - len;
        Ans_2[id] = len*(len-1);
        ll g = gcd(Ans_1[id],Ans_2[id]);
        Ans_1[id] /= g;Ans_2[id] /= g;
    }
}

int main(){
    scanf("%d%d",&n,&m);

    int siz = sqrt(1.0*m);
    for(int i=1 ;i<=n ;i++) scanf("%d",&a[i]),belong[i] = (i-1)/siz + 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+1+m);

    solve();
    for(int i=1 ;i<=m ;i++) printf("%lld/%lld\n",Ans_1[i],Ans_2[i]);
    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值