洛谷 P2709 小B的询问

洛谷 P2709 小B的询问

洛谷传送门

题目描述

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

∑i=1kci2sumlimits_{i=1}^k c_i^2 i=1∑kci2

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

输入格式

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

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

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

输出格式

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


题解:

莫队普通的裸题。

作为莫队入门题使用。

代码:

#include<cstdio>
#include<cmath>
#include<algorithm>
#define int long long
using namespace std;
const int maxn=5e4+4;
int n,m,k;
int a[maxn],b[maxn];
int cnt[maxn],ans[maxn];
struct node
{
    int l,r,id,pos;
}q[maxn];
bool cmp(node x,node y)
{
    if(x.pos==y.pos)
        return x.r<y.r;
    return x.pos<y.pos;
}
signed main()
{
    scanf("%lld%lld%lld",&n,&m,&k);
    int block=sqrt(n);
    for(int i=1;i<=n;i++)
    {
        scanf("%lld",&a[i]);
        b[i]=(i-1)/block+1;
    }
    for(int i=1;i<=m;i++)
    {
        scanf("%lld%lld",&q[i].l,&q[i].r);
        q[i].id=i;
        q[i].pos=b[q[i].l];
    }
    sort(q+1,q+m+1,cmp);
    int l=1,r=0;
    int tmp=0;
    for(int i=1;i<=m;i++)
    {
        while(l>q[i].l)
            l--,cnt[a[l]]++,tmp+=(2*cnt[a[l]]-1);
        while(r<q[i].r)
            r++,cnt[a[r]]++,tmp+=(2*cnt[a[r]]-1);
        while(l<q[i].l)
            cnt[a[l]]--,tmp-=(2*cnt[a[l]]+1),l++;
        while(r>q[i].r)
            cnt[a[r]]--,tmp-=(2*cnt[a[r]]+1),r--;
        ans[q[i].id]=tmp;
    }
    for(int i=1;i<=m;i++)
        printf("%lld
",ans[i]);
    return 0;
}
原文地址:https://www.cnblogs.com/fusiwei/p/14044867.html