P2709 小B的询问

题目:

https://www.luogu.com.cn/problem/P2709

大意:求出从[1,k]再给出的区间[l,r]中出现的次数的平方和

 

 因为数列是计数是从1开始的,所以要把L置为1,不然会把a[0]自动算上

#include<bits/stdc++.h>
#include<stdio.h>
using namespace std;
const int maxn=5e4+7;
int n,m,block,belong[maxn],arr[maxn],has[maxn],ans[maxn];

struct Q
{
    int l,r,id;
    bool operator <(const Q &b)
    {
        if(belong[l]!=belong[b.l])
            return l<b.l;
        else
            return r<b.r;
    }
}query[maxn];
int L,R,ret;
inline void add(int x)
{
    ret-=has[x]*has[x];
    ++has[x];
    ret+=has[x]*has[x];
}
inline void del(int x)
{
    ret-=has[x]*has[x];
    --has[x];
    ret+=has[x]*has[x];
}
//从[L,R]转移到[l,r]
/*
void GetNew(int l,int r,int L,int R)
{
    while(R<r) add(arr[++R]);
    while(L>l) add(arr[--L]);
    while(R>r) del(arr[R--]);
    while(L<l) del(arr[L++]);
}
*/
int main()
{   int k;
    scanf("%d%d%d",&n,&m,&k);
     block=sqrt(n);

  for(int i=1;i<=n;++i)
  {  scanf("%d",&arr[i]);
       belong[i]=(i-1)/block+1;
  }
  for(int i=1;i<=m;++i)
  {
    int l,r;
    scanf("%d%d",&l,&r);
    query[i]={l,r,i};
  }
  sort(query+1,query+m+1);
  L=1;
  for(int i=1;i<=m;++i)
  {  int l=query[i].l;
     int r=query[i].r;
     int id=query[i].id;
      //auto[l,r,id]=query[i];
      while(R<r) add(arr[++R]);
      while(L>l) add(arr[--L]);
      while(R>r) del(arr[R--]);
      while(L<l) del(arr[L++]);
      ans[id]=ret;
  }
  for(int i=1;i<=m;++i)
    printf("%d\n",ans[i]);
}

 

posted @ 2021-08-11 20:34  废柴废柴少女  阅读(63)  评论(0)    收藏  举报