【洛谷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;
}

猜你喜欢

转载自www.cnblogs.com/wzj-xhjbk/p/10618532.html