题目链接: Click_here~
0 0.。。
题目意思就是统计出多少个某个数字出现了多少次。假设 3,1都出现了5次。。 则和是 5*5*5+5*5*5
因为是10秒。。分块无压力。。
#include <cstdio>
#include <cstdlib>
#include <iostream>
using namespace std;
#define LL long long
const int N = 133333;
const int Sqrt = 555;
int a[N],b[N],cnt[N],ll[N],rr[N],idx[N];
int n,q;
bool cmp(int x,int y){
if(ll[x]/Sqrt == ll[y]/Sqrt)
return rr[x] < rr[y];
return ll[x] < ll[y];
}
LL ret , ans[N] ,F[N];
int main(){
for(int i = 0;i < N;i++) F[i] = (LL)i*i*i;
while(scanf("%d",&n)!=EOF){
memset(cnt,0,sizeof(cnt));
for(int i = 0;i < n;i++) scanf("%d",a+i);
memcpy(b,a,sizeof(a));
sort(b,b+n);
int sz = unique(b,b+n)-b;
for(int i=0;i<n;i++) a[i] = lower_bound(b,b+sz,a[i])-b;
scanf("%d",&q);
for(int i=0;i<q;i++) idx[i] = i;
for(int i=0;i<q;i++) scanf("%d %d",&ll[i],&rr[i]);
sort(idx,idx+q,cmp);
int ql = 0 , qr = -1;
ret = 0;
for(int i=0;i<q;i++){
int l = ll[idx[i]] , r = rr[idx[i]];
l--,r--;
while(qr < r){
ret -= F[cnt[a[++qr]]];
ret += F[++cnt[a[qr]]];
}
while(ql > l){
ret -= F[cnt[a[--ql]]];
ret += F[++cnt[a[ql]]];
}
while(qr > r){
ret -= F[cnt[a[qr]]];
ret += F[--cnt[a[qr--]]];
}
while(ql < l){
ret -= F[cnt[a[ql]]];
ret += F[--cnt[a[ql++]]];
}
ans[idx[i]] = ret;
}
for(int i = 0;i < q;i++)
//cout << ans[i] << endl;
printf("%I64d\n",ans[i]);
}
return 0;
}