[Codeforces 220B]Little Elephant and Array(莫队)(扫描线)(树状数组)

Little Elephant and Array(扫描线)(树状数组)题目大意:给出一个长度为n的序列,进行m次询问。每次询问区间[l,r]内,有多少个数字x xx刚好出现了x xx次。题目思路:用扫描线+树状数组的去考虑枚举右端点r rr,维护左端点l ll,设法将s u m ( l , r ) sum(l,r)sum(l,r)表示为区间内的合法数字个数所以以区间[ 2 , 2 , 2 , 2 ] [2,2,2,2][2,2,2,2]为例:1.r = 1 r = 1r=1,左端点的贡献
摘要由CSDN通过智能技术生成

[Codeforces 220B]Little Elephant and Array(扫描线)(树状数组)

首先感谢光哥的样例,这是光哥的博客

这里是原题链接

原题题意
给出一个长度为n的序列,进行m次询问。
每次询问区间[l,r]内,有多少个数字x刚好出现了x次(出现次数和他数值本身相等)。

题目思路:
有的是,直接上莫队,优化询问.本博客用莫队的思想(排序查询)+扫描线的思想+树状数组去实现的
枚举右端点r,维护左端点l,设法将sum(l,r)表示为区间内的合法数字个数

以区间[2,2,2,2]为例,下标从1开始
1.r=1时,向右滚动左端点,其sum(l,r)分别为:[0,‘还没到这里’,‘还没到这里’,‘还没到这里’];
'0’出现的原因是:sum(1,1)不合法,所以贡献为0.
2.r=2时,向右滚动左端点,其sum(l,r)分别为:[1,0,还没到这里,还没到这里];
"1"出现的原因是:区间[1,2]内都为2,个数刚好为2个,满足要求,所以此处的sum(1,2)为1.

3.r=3时,向右滚动左端点,其sum(l,r)分别为:[−1,1,0,还没到这里];
我们从右向左解释,r=3,此时最右侧的sum(3,3)为0没问题,sum(2,3)=1,出现的理由同上, 区间[1,3]内有3个数字2,不满足条件,所以sum(1,3)必须为0,所以我们构造时令下标为1处为"-1",这样求和时sum(1,3)就为0了.

4.r=4时,向右滚动左端点,其sum(l,r)分别为:[0,−1,1,0];
此时的查询结果:
sum(4,4)=0,sum(3,4)=1,sum(2.4)=0,sum(1,4)=0.
合理合法.怎么查询都对.
所以可以看出规律,只需要维护上述规律即可将贡献维护。
查询时树状数组就可以完成任务

还没看懂的话,一定要看代码旁的注释:

multiset:点击了解
树状数组:点击了解
扫描线:点击了解
AC代码:

#include<bits/stdc++.h>
#pragma GCC optimize(2)
#define closeSync ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i<(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b)<
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值