CodeForces 86D Powerful array(莫队)

题意:给你一列数,对于区间LR,中的每一个数,我们都计算他出现了X次,然后价值就是x*x*这个数,然后加和就行了

思路:很久没有写过莫队,有一点点忘了,莫队的公式就是把(x+1)^2展开就可以得到,注意爆int

代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn=2e5+7;
int block,a[maxn],cnt[1000007];
LL res[maxn];
LL ans;
struct node
{
    int l,r,id;
}q[maxn];
bool cmp(node a,node b)
{
    return a.l/block!=b.l/block?a.l/block<b.l/block:a.r<b.r;
}
void update(int p,int val)
{
    if(val==1){
        ans+=cnt[a[p]]*2*a[p]+a[p];
        cnt[a[p]]++;
    }
    else{
        ans-=cnt[a[p]]*2*a[p];
        ans+=a[p];
        cnt[a[p]]--;
    }
}
int main()
{
    int n,t;
    while(~scanf("%d%d",&n,&t)){
        memset(cnt,0,sizeof(cnt));
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
        }
        block=sqrt(n);
        for(int i=1;i<=t;i++){
            scanf("%d%d",&q[i].l,&q[i].r);
            q[i].id=i;
        }
        sort(q+1,q+1+t,cmp);
        ans=0;
        for(int i=1,l=1,r=0;i<=t;i++){
            for(;r<q[i].r;r++)
                update(r+1,1);
            for(;r>q[i].r;r--)
                update(r,-1);
            for(;l<q[i].l;l++)
                update(l,-1);
            for(;l>q[i].l;l--)
                update(l-1,1);
            res[q[i].id]=ans;
        }
        for(int i=1;i<=t;i++){
            printf("%lld
",res[i]);
        }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/lalalatianlalu/p/9345874.html