[BZOJ 3781] 小B的询问

Link:

BZOJ 3781 传送门

Solution:

莫队裸题,只不过把维护的值改成了$\sum cnt[i]^2$

Code:

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int MAXN=50005;
ll sum=0,res[MAXN];
int n,m,k,blk,dat[MAXN],cnt[MAXN];
struct Query{int l,r,id;}qry[MAXN];

int cal(int x){return (x-1)/blk+1;}
bool cmp(Query x,Query y)
{return (cal(x.l)!=cal(y.l))?x.l<y.l:x.r<y.r;}

void update(int pos,int k)
{
    int &t=cnt[dat[pos]];
    sum-=1ll*t*t;t+=k;sum+=1ll*t*t;
}

int main()
{
    scanf("%d%d%d",&n,&m,&k);blk=sqrt(n);
    for(int i=1;i<=n;i++) scanf("%d",&dat[i]);
    for(int i=1;i<=m;i++)
        scanf("%d%d",&qry[i].l,&qry[i].r),qry[i].id=i;
    sort(qry+1,qry+m+1,cmp);
    
    int l=1,r=0;
    for(int i=1;i<=m;i++)
    {
        while(l<qry[i].l) update(l++,-1);
        while(l>qry[i].l) update(--l,1);
        while(r<qry[i].r) update(++r,1);
        while(r>qry[i].r) update(r--,-1);
        res[qry[i].id]=sum;
    }
    
    for(int i=1;i<=m;i++) printf("%d\n",res[i]);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/newera/p/9363258.html