分块专题2
cf 455D
题目要求
题意:给出一个序列,两种操作
1.将区间[l,r]滚动一次 a[l] a[l+1]···a[r]->a[r] a[l]···a[r-1]
2.询问区间[l,r]中值等于k的数有多少个
根据所给公式强制在线
参考AC代码
|
|
思路
分块+双段队列模拟
b代表每个块的hash表 que模拟每个块
模拟时注意细节即可 每个块que的下标需要减去左端点l
codeforces 13E
题目要求
有n个弹簧,每次扔个球,这个球可以弹到i+power[i]的位置
然后有两种操作
将第i个位置的弹簧的弹力改为b
将球扔到第i个位置,问这个球最后弹到了哪儿,这个球弹了几次?
参考AC代码
|
|
思路
跟bzoj弹飞绵羊一样 多了一个输出终止位置
这个在solve里暴力一下就好了
codeforces 551E
题目要求
对于给定数列,操作一是把[l,r]区间内的数加x,操作二是求出一个值,该值为数x出现的最右位置减最左位置,若不存在x输出为-1
参考AC代码
|
|
思路
对于这种迷之询问,用分块。将n个数分成sqrt(n)块,初始化将a数组赋值给d数组,将d数组分块从小到大排序,新建一个数组p储存每一块所加的和,
注意寻找最左侧和最右侧的二分写法
cf 103D
题目要求
给你N个数,然后每次询问给你(x,y),求a[x]+a[x+y]+a[x+2y]+a[x+3y]的和是多少
参考AC代码
|
|
思路
分块+离线
按照间隔y大小的sqrt分块 本题limit为:600
大于600直接暴力 小于600按照limit把询问的编号记录下来
对于每个limit按照dp预处理出每个位置 再更新ans
bzoj 2957
题目要求
小A的楼房外有一大片施工工地,工地上有N栋待建的楼房。每天,这片工地上的房子拆了又建、建了又拆。他经常无聊地看着窗外发呆,
数自己能够看到多少栋房子。
为了简化问题,我们考虑这些事件发生在一个二维平面上。小A在平面上(0,0)点的位置,第i栋楼房可以用一条连接(i,0)和(i,Hi)的线段表示,
其中Hi为第i栋楼房的高度。如果这栋楼房上任何一个高度大于0的点与(0,0)的连线没有与之前的线段相交,那么这栋楼房就被认为是可见的。
施工队的建造总共进行了M天。初始时,所有楼房都还没有开始建造,它们的高度均为0。在第i天,建筑队将会将横坐标为Xi的房屋的高度变为Yi
(高度可以比原来大—修建,也可以比原来小—拆除,甚至可以保持不变—建筑队这天什么事也没做)。请你帮小A数数每天在建筑队完工之后,
他能看到多少栋楼房?
第一行两个正整数N,M
接下来M行,每行两个正整数Xi,Yi
输出M行,第i行一个整数表示第i天过后小A能看到的楼房有多少栋
参考AC代码
|
|
思路
能使用线段树的条件是:两个子问题可以合并
本题中,记ans[o]为:仅考虑o所代表的区间,有多少满足条件的数
那么首先,ans[o]一定包含ans[o×2]; 其次,属于ans[o×2]的建筑有可能挡住属于ans[o×2+1]的建筑,难点在于需求出这个数目
记 o×2 代表的区间中最大数为M,并将 o×2+1 所代表的区间分左右两段,记左段代表的区间中最大数为M2,继续讨论:
- 若M大于等于M2,则左段全部不符合要求,递归判断右段有多少个大于M的数
- 若M小于M2,则右段的答案不变,为ans[o×2+1]-ans[左段],递归判断左段有多少个大于M的数
hihocoder 1236
题目要求
q次询问 每次寻找五维偏序
要求每次ans[i]的值异或flag
参考AC代码
|
|
思路
在hihocoder147周的基础上分块
对于每次询问ans[i]二分查找到小于等于key的第一个位置 再进行块的处理
由于本题的q是在线的 所以需要排序分块二分
具体题解参考链接转跳链接