【洛谷P2709】小B的询问
题目大意:给定一个长度为 N 的序列,M 个询问,静态查询区间 [l,r] 内的不同颜色数的平方和。
题解:直接莫队即可。
代码如下
#include <bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define all(x) x.begin(),x.end()
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
const int mod=1e9+7;
const int inf=0x3f3f3f3f;
const int maxn=5e4+10;
inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
inline ll sqr(ll x){return x*x;}
inline ll read(){
ll x=0,f=1;char ch;
do{ch=getchar();if(ch=='-')f=-1;}while(!isdigit(ch));
do{x=x*10+ch-'0';ch=getchar();}while(isdigit(ch));
return f*x;
}
int n,m,range,c[maxn],cnt[maxn];ll ans,ret[maxn];
struct node{int l,r,id,bl;}q[maxn];
int size;
bool cmp(const node &a,const node &b){return a.bl==b.bl?a.r<b.r:a.bl<b.bl;}
void read_and_parse(){
n=read(),m=read(),range=read();
for(int i=1;i<=n;i++)c[i]=read();
size=sqrt(n);
for(int i=1;i<=m;i++)q[i].l=read(),q[i].r=read(),q[i].bl=(q[i].l-1)/size+1,q[i].id=i;
sort(q+1,q+m+1,cmp);
}
inline void update(int pos,int val){
ans-=sqr(cnt[c[pos]]);
cnt[c[pos]]+=val;
ans+=sqr(cnt[c[pos]]);
}
void solve(){
for(int i=1,l=1,r=0;i<=m;i++){
while(r<q[i].r)update(r+1,1),++r;
while(r>q[i].r)update(r,-1),--r;
while(l<q[i].l)update(l,-1),++l;
while(l>q[i].l)update(l-1,1),--l;
ret[q[i].id]=ans;
}
for(int i=1;i<=m;i++)printf("%lld\n",ret[i]);
}
int main(){
read_and_parse();
solve();
return 0;
}