http://codeforces.com/problemset/problem/86/D
題意就是每種數字x對答案的貢獻是(x*x*出現次數),是以add函數和del函數就很明顯了。
但是由于讀入比較多,需要挂個簡單的讀入挂
代碼
#include<stdio.h>
#include<math.h>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int maxn = +;
int a[maxn];
long long sum[maxn];
int pos[maxn];
long long ans[maxn];
struct data
{
int l,r,id;
}Q[maxn];
bool cmp(const data &a,const data &b)
{
if(pos[a.l]==pos[b.l]) return a.r<b.r;
return pos[a.l]<pos[b.l];
}
int L=,R=;
long long Ans=;
void add(int x)
{
sum[a[x]]++;
Ans+=(L*(L*sum[a[x]]-)*a[x]);//算出簡單的轉移減少常數
}
void del(int x)
{
sum[a[x]]--;
Ans-=(L*(L*sum[a[x]]+)*a[x]);
}
int read()
{
ll x=;
char c=getchar();
while(c < '0' || c > '9')
{
c = getchar();
}
while(c >= '0' && c <= '9')
{
x = x * + c - '0';
c = getchar();
}
return x;
}
int main()
{
int n,t;
scanf("%d%d",&n,&t);
int sz=sqrt(n);
for(int i=;i<=n;i++)
{
a[i]=read();
pos[i]=i/sz;
}
for(int i=;i<=t;i++)
{
Q[i].l=read();
Q[i].r=read();
Q[i].id=i;
}
sort(Q+,Q++t,cmp);
for(int i=;i<=t;i++)
{
while(L>Q[i].l)
{
L--;
add(L);
}
while(R<Q[i].r)
{
R++;
add(R);
}
while(L<Q[i].l)
{
del(L);
L++;
}
while(R>Q[i].r)
{
del(R);
R--;
}
ans[Q[i].id]=Ans;
}
for(int i=;i<=t;i++) printf("%I64d\n",ans[i]);
return ;
}