[洛谷 P2709] 小B的询问

P2709 小B的询问

题目描述

小B有一个序列,包含N个1~K之间的整数。他一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数字i在[L..R]中的重复次数。小B请你帮助他回答询问。

输入输出格式

输入格式:

第一行,三个整数N、M、K。

第二行,N个整数,表示小B的序列。

接下来的M行,每行两个整数L、R。

输出格式:

M行,每行一个整数,其中第i行的整数表示第i个询问的答案。

输入输出样例

输入样例#1:
6 4 3
1 3 2 1 1 3
1 4
2 6
3 5
5 6
输出样例#1:
6
9
5
2

说明

对于全部的数据,1<=N、M、K<=50000

有了莫队算法的铺垫,那么做这题就简单了。

同样,还是一样的套路,只是在统计ans的时候改变了一下。

在add函数中:

由于加入了某一个,所以该种颜色c[i]数目从x变为x+1,则总数+=(x+1)^2-x^2=2x+1

在remove函数中:

由于删去了某一个,所以该种颜色c[i]数目从x变为x-1,则总数-=x^2-(x-1)^2=2x-1

有了这两个式子,问题就迎刃而解了。

 #include<cstdio>
 #include<cstring>
 #include<algorithm>
 #include<cmath>
 using namespace std;
 ],c[],ans;
 struct query{
     int L,R,index,ans;
 }a[];
 inline int read(){
     ; char ch=getchar();
     ') ch=getchar();
     +ch-',ch=getchar();
     return x;
 }
 bool cmp(query u,query v){return u.L/blocks==v.L/blocks?u.R<v.R:u.L<v.L;}
 bool cmp_id(query u,query v){return u.index<v.index;}
 |;}
 |,cnt[c[p]]++;}
 int main(){
     n=read(),Q=read(),K=read(),blocks=sqrt(n);
     ; i<=n; i++) c[i]=read();
     ; i<=Q; i++) a[i].L=read(),a[i].R=read(),a[i].index=i;
     sort(a+,a++Q,cmp);
     ,curR=;
     memset(cnt,,;
     ; i<=Q; i++){
         while (curL<a[i].L) remove(curL++);
         while (curR>a[i].R) remove(curR--);
         while (curL>a[i].L) add(--curL);
         while (curR<a[i].R) add(++curR);
         a[i].ans=ans;
     }
     sort(a+,a++Q,cmp_id);
     ; i<=Q; i++) printf("%d\n",a[i].ans);
     ;
 }
上一篇:nexus-3.2.0-01.zip安装以及如何启动服务


下一篇:P2709 小B的询问 (莫队板子)