BZOJ3781 小B的询问 莫队

来源:互联网 发布:快刀软件多少钱? 编辑:程序博客网 时间:2024/05/17 22:35
小B有一个序列,包含N个1~K之间的整数。他一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数字i在[L..R]中的重复次数。n,m,K<=50000.

显然莫队裸题,样例一遍过。。。

#include<bits/stdc++.h>#define LL long long#define clr(x,i) memset(x,i,sizeof(x))using namespace std;const int N=50005;int n,m,K,a[N],tim,cnt[N],curL,curR;LL res,ans[N];struct Q{int l,r,id;friend bool operator <(Q a,Q b){return a.l/tim==b.l/tim ? a.r<b.r : a.l<b.l;}}q[N];inline void add(int x){int v=a[x];res+=2*cnt[v]+1;cnt[v]++;}inline void remove(int x){int v=a[x];res-=2*cnt[v]-1;cnt[v]--;}void solve(){int l,r;curL=1,curR=0;for(int i=1;i<=n;i++){l=q[i].l,r=q[i].r;while(curL<l)  remove(curL++);while(curL>l)  add(--curL);while(curR>r)  remove(curR--);while(curR<r)  add(++curR);ans[q[i].id]=res;}}int main(){scanf("%d%d%d",&n,&m,&K);for(int i=1;i<=n;i++)  scanf("%d",&a[i]);tim=sqrt(n);for(int i=1;i<=m;i++){scanf("%d%d",&q[i].l,&q[i].r);q[i].id=i;}sort(q+1,q+m+1);solve();for(int i=1;i<=m;i++)  printf("%lld\n",ans[i]);return 0;}


原创粉丝点击