BZOJ3781 小B的询问 莫队

1 篇文章 0 订阅
小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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值