由于10^9很大,所以先离散化一下,把给你的这一段数哈希 时间复杂度O(nlogn)
然后就是分块莫队 已知[L,R],由于事先的离散化,可以在O(1)的的时间更新[l+1,r],[l,r+1],[l-1,r],[l,r-1]时间复杂度O(n*sqrt(n));
代码如下,速度并不是很快(我比较喜欢手动的去重,unique一直没怎么用过)
/*96655 's source code for B
Memory: 3744 KB Time: 2968 MS
Language: G++ Result: Accepted
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<iostream>
#include<cstdlib>
#include<queue>
#include<map>
#include<set>
#include<cmath>
using namespace std;
typedef long long LL;
const int maxn=;
map<int,int>mp;
int a[maxn],pos[maxn],b[maxn];
LL sum;
struct node
{
int l,r,id;
LL ans;
} res[maxn];
bool cmp1(node a,node b)
{
if(pos[a.l]==pos[b.l])return a.r<b.r;
return a.l<b.l;
}
bool cmp2(node a,node b)
{
return a.id<b.id;
}
void change(int pos,int op)
{ LL temp=b[a[pos]];
sum-=temp*temp*temp;
b[a[pos]]+=op;
temp=b[a[pos]];
sum+=temp*temp*temp;
}
int main()
{
int n,q;
while(~scanf("%d",&n))
{
double cn=n;
int blk=(int)(sqrt(cn));
sum=,mp.clear();
for(int i=; i<=n; ++i)
scanf("%d",&a[i]),pos[i]=(i-)/blk+,b[i]=a[i];
sort(b+,b+n+);
int cnt=;
for(int i=; i<=n; ++i)
if(b[i]!=b[i-])b[cnt++]=b[i];
--cnt;
for(int i=; i<=n; ++i)
a[i]=lower_bound(b+,b++cnt,a[i])-(b+);
memset(b,,sizeof(b));
scanf("%d",&q);
for(int i=; i<=q; ++i)
scanf("%d%d",&res[i].l,&res[i].r),res[i].id=i;
sort(res+,res++q,cmp1);
for(int i=,l=,r=; i<=q; ++i)
{
for(; r<res[i].r; ++r)
change(r+,);
for(; r>res[i].r; --r)
change(r,-);
for(; l<res[i].l; ++l)
change(l,-);
for(; l>res[i].l; --l)
change(l-,);
res[i].ans=sum;
}
sort(res+,res+q+,cmp2);
for(int i=; i<=q; ++i)
printf("%I64d\n",res[i].ans);
}
return ;
}