Codeforces 86D Powerful array(莫队算法)

时间:2022-04-18 19:58:35

莫队算法的裸题。n^2可以展开成等差数列1+3+5....+2*n-1的和,这样一来插入和删除操作就变得简单多了。

#include<cstdio>
#include<cmath>
#include<algorithm>
#define MAXN 200010
using namespace std;
int a[MAXN],n,t,block,cnt[1000010];
long long ans[MAXN],now;
struct Q
{
	int l,r,id;
	bool operator <(const Q &b)const
	{
		if(l/block == b.l/block) return r < b.r;
		return l < b.l; 
	}
}que[MAXN];
void add(int x)
{
	now += (2*cnt[x]+1)*x;
	cnt[x]++;
}
void del(int x)
{
	now += (-2*cnt[x]+1)*x;
	cnt[x]--;
}
int main()
{
	scanf("%d%d",&n,&t);
	for(int i = 1; i <= n; i++) scanf("%d",&a[i]);
	block = sqrt(n);
	for(int i = 0; i < t; i++)
	{
		scanf("%d%d",&que[i].l,&que[i].r);
		que[i].id = i;
	}
	sort(que,que+t);
	int currentL = 1,currentR = 0;
	for(int i = 0; i < t; i++)
	{
		while(que[i].l < currentL) add(a[--currentL]);
		while(que[i].l > currentL) del(a[currentL++]);
		while(que[i].r > currentR) add(a[++currentR]);
		while(que[i].r < currentR) del(a[currentR--]);	
		ans[que[i].id] = now;
	}
	for(int i = 0; i < t; i++)
		printf("%I64d\n",ans[i]);
}