An array of positive integers a1, a2, …, an is given. Let us consider its arbitrary subarray al, al + 1…, ar, where 1 ≤ l ≤ r ≤ n. For every positive integer s denote by Ks the number of occurrences of s into the subarray. We call the power of the subarray the sum of products Ks·Ks·s for every positive integer s. The sum contains only finite number of nonzero summands as the number of different values in the array is indeed finite.
You should calculate the power of t given subarrays.
Input
First line contains two integers n and t (1 ≤ n, t ≤ 200000) — the array length and the number of queries correspondingly.
Second line contains n positive integers ai (1 ≤ ai ≤ 106) — the elements of the array.
Next t lines contain two positive integers l, r (1 ≤ l ≤ r ≤ n) each — the indices of the left and the right ends of the corresponding subarray.
Output
Output t lines, the i-th line of the output should contain single positive integer — the power of the i-th query subarray.
Please, do not use %lld specificator to read or write 64-bit integers in C++. It is preferred to use cout stream (also you may use %I64d).
Examples
Input
3 2
1 2 1
1 2
1 3
Output
3
6
Input
8 3
1 1 2 2 1 3 1 1
2 7
1 6
2 7
Output
20
20
20
题意:就是每种数字x对答案的贡献是(xx出现次数),求总贡献
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#define ll long long
using namespace std;
const int maxn=1000006;
int n,m,k,a[maxn],b[maxn],book[maxn];
ll cnt[maxn],ans[maxn],sum;
struct fun
{
int l;
int r;
int id;
}mo[maxn];
void add(int pos)
{
sum+=((2*cnt[a[pos]]+1)*a[pos]);
cnt[a[pos]]++;
}
void del(int pos)
{
cnt[a[pos]]--;
sum-=((2*cnt[a[pos]]+1)*a[pos]);
}
bool cmp(fun x,fun y)
{
return b[x.l]<b[y.l]||(b[x.l]==b[y.l]&&(b[x.l]&1?x.r<y.r:x.r>y.r));
// if(b[x.l]==b[y.l ])
// return x.r<y.r;
// else return x.l<y.l ;
}
int main()
{
scanf("%d%d",&n,&m);
int size=sqrt(n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
b[i]=i/size+1;
}
for(int i=0;i<m;i++)
{
scanf("%d%d",&mo[i].l ,&mo[i].r );
mo[i].id=i;
}
sort(mo,mo+m,cmp);
int l=1,r=0;
for(int i=0;i<m;i++)
{
while(l>mo[i].l)
{
add(l-1);
l--;
}
while(l<mo[i].l )
{
del(l);
l++;
}
while(r>mo[i].r)
{
del(r);
r--;
}
while(r<mo[i].r )
{
add(r+1);
r++;
}
ans[mo[i].id]=sum;
}
for(int i=0;i<m;i++)
{
printf("%lld\n",ans[i]);
}
}
很容易能算出,x²和 (x+1)²差值是2K+1,很容易就能套入add函数,del函数里面了。
也就是个模板题,但是我为什么TLE那么多次!!!居然是因为忘记对分块进行排序了o(╥﹏╥)o==可能是因为写的时候思绪太飘了。。。。。。这都能忘,唉
不过,这个莫队玄学奇偶性排序,确实比原来的(见下代码注释)要快那么一些。。。4116ms和4648ms,以后还是用这个排序方法吧!!
bool cmp(fun x,fun y)
{
return b[x.l]<b[y.l]||(b[x.l]==b[y.l]&&(b[x.l]&1?x.r<y.r:x.r>y.r));
// if(b[x.l]==b[y.l ])
// return x.r<y.r;
// else return x.l<y.l ;
}