题目描述
小B 有一个长为 n 的整数序列 a,值域为 [1,k]。
他一共有 m 个询问,每个询问给定一个区间 [l,r],求:sigma(i=1-k)ci^2
其中 ci 表示数字 i 在 [l,r] 中的出现次数。
小B请你帮助他回答询问。输入格式
第一行三个整数 n,m,k。
第二行 n 个整数,表示 小B 的序列。
接下来的 m 行,每行两个整数 l,r。
输出格式
输出 m 行,每行一个整数,对应一个询问的答案。
输入输出样例
输入 #1
6 4 3 1 3 2 1 1 3 1 4 2 6 3 5 5 6输出 #1
6 9 5 2说明/提示
【数据范围】
对于 100% 的数据 1≤n,m,k≤5×10^4。
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m,k;
const int maxn=5e4+5;
struct Q
{
int l,r,id,pos;//分别代表左边界、右边界、序号、所处sqrt(n)位置
} q[maxn];
int b[maxn],cnt[maxn],Ans[maxn];
int cmp(Q a,Q b)
{
if(a.pos==b.pos)
{
return a.r<b.r;
}
else
{
return a.pos<b.pos;
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n>>m>>k;
int siz=(int)sqrt(n);
for(int i=1; i<=n; i++)
{
cin>>b[i];
}
for(int i=1; i<=m; i++)
{
cin>>q[i].l>>q[i].r;
q[i].id=i;
q[i].pos=(q[i].l-1)/siz+1;
}
sort(q+1,q+1+m,cmp);
int l=1,r=0;
int ans=0;
for(int i=1; i<=m; i++)
{
//cout<<q[i].l<<" "<<q[i].r<<"\n";
while(l>q[i].l)l--,cnt[b[l]]++,ans+=2*cnt[b[l]]-1;
while(r<q[i].r)r++,cnt[b[r]]++,ans+=2*cnt[b[r]]-1;
while(l<q[i].l)cnt[b[l]]--,ans-=2*cnt[b[l]]+1,l++;
while(r>q[i].r)cnt[b[r]]--,ans-=2*cnt[b[r]]+1,r--;
Ans[q[i].id]=ans;
}
for(int i=1;i<=m;i++)cout<<Ans[i]<<"\n";
return 0;
}