同小Z的袜子,只是需要离散化,平方变成了立方
//#include<bits/stdc++.h>
#include<stdio.h>
#include<algorithm>
#include<string.h>
#include<math.h>
#define N 100010
#define LL long long
using namespace std;
struct node
{
int l,r,id;
};
int n,m,t;
int pos[N],c[N],a[N];
LL s[N],ans[N];
node q[N];
void init()
{
memset(s,0,sizeof(s));
int unit=int(sqrt(n));
for (int i=1;i<=n;i++)
if (i%unit==0) pos[i]=i/unit; else pos[i]=i/unit+1;
}
bool cmp(node a, node b)
{
if (pos[a.l]==pos[b.l]) return a.r<b.r;
else return pos[a.l]<pos[b.l];
}
LL gcd(LL a, LL b)
{
if (b==0) return a;
return gcd(b,a%b);
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
init();
for (int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
c[i]=a[i];
}
sort(a+1,a+n+1);
t=unique(a+1,a+n+1)-a-1;
for (int i=1;i<=n;i++) c[i]=lower_bound(a+1,a+t+1,c[i])-a;
scanf("%d",&m);
for (int i=1;i<=m;i++)
{
scanf("%d%d",&q[i].l,&q[i].r);
q[i].id=i;
}
sort(q+1,q+m+1,cmp);
int l=1,r=1;
LL tmp=1;
s[c[1]]=1;
for (int i=1;i<=m;i++)
{
while(r<q[i].r)
{
r++;
tmp=tmp-s[c[r]]*s[c[r]]*s[c[r]];
s[c[r]]++;
tmp=tmp+s[c[r]]*s[c[r]]*s[c[r]];
}
while(r>q[i].r)
{
tmp=tmp-s[c[r]]*s[c[r]]*s[c[r]];
s[c[r]]--;
tmp=tmp+s[c[r]]*s[c[r]]*s[c[r]];
r--;
}
while(l<q[i].l)
{
tmp=tmp-s[c[l]]*s[c[l]]*s[c[l]];
s[c[l]]--;
tmp=tmp+s[c[l]]*s[c[l]]*s[c[l]];
l++;
}
while(l>q[i].l)
{
l--;
tmp=tmp-s[c[l]]*s[c[l]]*s[c[l]];
s[c[l]]++;
tmp=tmp+s[c[l]]*s[c[l]]*s[c[l]];
}
ans[q[i].id]=tmp;
}
for (int i=1;i<=m;i++) printf("%I64d\n",ans[i]);
}
return 0;
}