题目链接:https://cn.vjudge.net/problem/NBUT-1457
题意:计算一个区间内,每种数 数量的三次方的和
题解:莫队算法走一遍即可,比较坑人的就是用sqrt(n*1.0)的时候要乘上1.0,否则就是CE死你
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
const int N=100010;
int CM;
struct node{
int id;
int l,r;
bool operator <(const node &x)const
{
if(l/CM != x.l/CM) return l/CM < x.l/CM;
else return r<x.r;
}
}q[N];
int n,m;
int a[N],b[N],len;
ll ans[N];
int num[N];
ll cul(int x)
{
return (ll)x*x*x;
}
int main()
{
ll res;
int l,r;
while(~scanf("%d",&n))
{
for(int i=1;i<=n;i++)scanf("%d",&a[i]),b[i]=a[i];
sort(b+1,b+1+n);
len=unique(b+1,b+1+n)-(b+1);
CM=(int)sqrt(n*1.0);
for(int i=1;i<=n;i++)
{
a[i]=lower_bound(b+1,b+1+len,a[i])-b;
// cout<<a[i]<<endl;
}
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
scanf("%d%d",&q[i].l,&q[i].r);
q[i].id=i;
ans[i]=0;
}
sort(q+1,q+1+m);
for(int i=1,j=1;j<=m;i++)
{
l=q[j].l+1,r=q[j].l;
res=0;
for(int k=0;k<=len;k++)
{
num[k]=0;
}
for(;j<=m && j<i*CM;j++)
{
while(l<q[j].l)
{
res=res-cul(num[a[l]])+cul(num[a[l]]-1);
num[a[l]]--;
l++;
}
while(l>q[j].l)
{
l--;
num[a[l]]++;
res=res+cul(num[a[l]])-cul(num[a[l]]-1);
}
while(r<q[j].r)
{
r++;
num[a[r]]++;
res=res+cul(num[a[r]])-cul(num[a[r]]-1);
}
while(r>q[j].r)
{
res=res-cul(num[a[r]])+cul(num[a[r]]-1);
num[a[r]]--;
r--;
}
ans[q[j].id]=res;
}
}
for(int i=1;i<=m;i++)
printf("%lld\n",ans[i]);
}
return 0;
}