P2709 小B的询问 莫队入门

题目描述

小B 有一个长为 n 的整数序列 a,值域为 [1,k]。
他一共有 m 个询问,每个询问给定一个区间 [l,r],求:

sigma(i=1-k)ci^2

其中 ci​ 表示数字 i 在 [l,r] 中的出现次数。
小B请你帮助他回答询问。

输入格式

第一行三个整数 n,m,k。

第二行 n 个整数,表示 小B 的序列。

接下来的 m 行,每行两个整数 l,r。

输出格式

输出 m 行,每行一个整数,对应一个询问的答案。

输入输出样例

输入 #1

6 4 3
1 3 2 1 1 3
1 4
2 6
3 5
5 6

输出 #1

6
9
5
2

说明/提示

【数据范围】
对于 100% 的数据 1≤n,m,k≤5×10^4。

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m,k;
const int maxn=5e4+5;
struct Q
{
    int l,r,id,pos;//分别代表左边界、右边界、序号、所处sqrt(n)位置
} q[maxn];
int b[maxn],cnt[maxn],Ans[maxn];
int cmp(Q a,Q b)
{
    if(a.pos==b.pos)
    {
        return a.r<b.r;
    }
    else
    {
        return a.pos<b.pos;
    }
}
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin>>n>>m>>k;
    int siz=(int)sqrt(n);
    for(int i=1; i<=n; i++)
    {
        cin>>b[i];
    }
    for(int i=1; i<=m; i++)
    {
        cin>>q[i].l>>q[i].r;
        q[i].id=i;
        q[i].pos=(q[i].l-1)/siz+1;
    }
    sort(q+1,q+1+m,cmp);
    int l=1,r=0;
    int ans=0;
    for(int i=1; i<=m; i++)
    {
       //cout<<q[i].l<<" "<<q[i].r<<"\n";
        while(l>q[i].l)l--,cnt[b[l]]++,ans+=2*cnt[b[l]]-1;
        while(r<q[i].r)r++,cnt[b[r]]++,ans+=2*cnt[b[r]]-1;
        while(l<q[i].l)cnt[b[l]]--,ans-=2*cnt[b[l]]+1,l++;
        while(r>q[i].r)cnt[b[r]]--,ans-=2*cnt[b[r]]+1,r--;
        Ans[q[i].id]=ans;
    }
    for(int i=1;i<=m;i++)cout<<Ans[i]<<"\n";

    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值