莫队算法的裸题。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]); }