分块专题一
bzoj 3343
题目要求
区间初始值ai 给出两种操作
区间l到r内加w
区间l到r内询问大于等于w的个数
参考AC代码
|
|
思路
num:分块的个数
belong[i]:表示i属于哪一块
block:表示块的大小
l[i]:表示i这块的左端点位置
r[i]:表示右端点位置
数组p相当于lazy 每个块内排序 最后完整的块用二分找到大于等于w的位置
当区间修改的端点经过了不完整的区间 这一段的lazy要加到a上 并更新到d上 因为lazy代表的是这一整块的延迟标记
bzoj 4636
题目要求
蒟蒻DCrusher不仅喜欢玩扑克,还喜欢研究数列
题目描述
DCrusher有一个数列,初始值均为0,他进行N次操作,每次将数列[a,b)这个区间中所有比k小的数改为k,他想知
道N次操作后数列中所有元素的和。他还要玩其他游戏,所以这个问题留给你解决。
参考AC代码
|
|
思路
这题这可以用分块做 但还是采用离散+离线线段树处理
区间范围1e9所以需要离散化
sum维护离散化后每个点与后一个点的差 实际维护的是该段lazy的区间长度
注意是左闭右开的区间 所以R需要-1
还需主要vector下标从0开始 所以计算sum的时候需要后移一位
bzoj 2002
题目要求
某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏。游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,
每个装置设定初始弹力系数ki,当绵羊达到第i个装置时,它会往后弹ki步,达到第i+ki个装置,若不存在第i+ki个装置,则绵羊被弹飞。绵羊想知道当它从第i个装置起步时,
被弹几次后会被弹飞。为了使得游戏更有趣,Lostmonkey可以修改某个弹力装置的弹力系数,任何时候弹力系数均为正整数。
第一行包含一个整数n,表示地上有n个装置,装置的编号从0到n-1,接下来一行有n个正整数,依次为那n个装置的初始弹力系数。第三行有一个正整数m,接下来m行每行
至少有两个数i、j,若i=1,你要输出从j出发被弹几次后被弹飞,若i=2则还会再输入一个正整数k,表示第j个弹力装置的系数被修改成k。对于20%的数据n,m<=10000,
对于100%的数据n<=200000,m<=100000
对于每个i=1的情况,你都要输出一个需要的步数,占一行。
参考AC代码
|
|
思路
分块
cnt维护跳出该块的步数
end维护跳到下一个块的位置
注意下标从0开始 x需要++
cf 444c
题目要求
开始,a[i]=i,b[i]=0
然后两个操作
1.使得[l,r]的b[i]+=fabs(x-a[i]),a[i]=x
2.查询[l,r]的b[i]和
参考AC代码
|
|
思路
可以用分块做 本题采用线段树 但用了分块的思想
same表示区间的颜色是否相同 0表示不同
每次更新的时候找到颜色相同的块更新
bzoj 2120
题目要求
墨墨购买了一套N支彩色画笔(其中有些颜色可能相同),摆成一排,你需要回答墨墨的提问。墨墨会像你发布如下指令:
1、 Q L R代表询问你从第L支画笔到第R支画笔中共有几种不同颜色的画笔。 2、 R P Col 把第P支画笔替换为颜色Col。
为了满足墨墨的要求,你知道你需要干什么了吗?
第1行两个整数N,M,分别代表初始画笔的数量以及墨墨会做的事情的个数。第2行N个整数,分别代表初始画笔排中第i支画笔的颜色。
第3行到第2+M行,每行分别代表墨墨会做的一件事情,格式见题干部分。
对于每一个Query的询问,你需要在对应的行中给出一个数字,代表第L支画笔到第R支画笔中共有几种不同颜色的画笔。
参考AC代码
|
|
思路
分块
也可以用线段树 参考muti多校4
数组c表示颜色 数组b记录每一个位置颜色上一次的出现位置 last维护每种颜色的上一次出现位置 a和b相同 用来二分查找
对于每一块 b[i]<l就代表这个数字出现了一次 ans++
更新操作里 temp记录上一次的b[i]值 如果和这次更新的不一样 那么这一段重新更新排序
注意数组要开100w 因为last记录的是颜色
cdoj 1292
题目要求
卿学姐有n个花坛,一开始第i个花坛里有A[i]朵花。每过一段时间,卿学姐都会在花坛里种上新的花。
作为一个聪明的学姐,卿学姐的种花方式也是与众不同 , 每一次,卿学姐会在第x个花坛种上y朵花,然后在第x+1个花坛上种上y−1朵花,
再在第x+2个花坛上种上y−2朵花……以此类推,直到种到最后一个花坛,或者不需要种花为止。
喵哈哈的村民们都喜欢去卿学姐的后院赏花,沈宝宝也不例外。然而沈宝宝可不是省油的灯,怎么可能会老老实实地赏花呢。每次沈宝宝来时,
都会随机询问卿学姐在第i个花坛有多少朵花。
第一行输入两个整数,花坛个数NN和操作次数Q。
第二行NN个整数A[1],A[2],A[3]…A[N] (1≤A[i]≤2^31)
接下来Q行,每行一个操作。
1 x y 表示卿学姐会在x号花坛种y朵花,并按相应的规律在后面的花坛上种花。
2 x 表示沈宝宝问卿学姐第x个花坛有多少朵花。
对于每个询问操作,按顺序输出答案对772002+233取模的值。
参考AC代码
|
|
思路
对于这种乱更新乱询问的 分块暴力即可
散块直接暴力 lazy把延迟标记打在块的左端点上 num记录有多少次更新打在左端点上 ed表示有多少次终止
最后对x所在的区间进行更新 逐位加lazy并减Num 如果碰到ed还要–
HUD 4858
题目要求
我们建造了一个大项目!这个项目有n个节点,用很多边连接起来,并且这个项目是连通的!
两个节点间可能有多条边,不过一条边的两端必然是不同的节点。
每个节点都有一个能量值。
现在我们要编写一个项目管理软件,这个软件呢有两个操作:
1.给某个项目的能量值加上一个特定值。
2.询问跟一个项目相邻的项目的能量值之和。(如果有多条边就算多次,比如a和b有2条边,那么询问a的时候b的权值算2次)
第一行一个整数T(1 <= T <= 3),表示测试数据的个数。
然后对于每个测试数据,第一行有两个整数n(1 <= n <= 100000)和m(1 <= m <= n + 10),分别表示点数和边数。
然后m行,每行两个数a和b,表示a和b之间有一条边。
然后一个整数Q。
然后Q行,每行第一个数cmd表示操作类型。如果cmd为0,那么接下来两个数u v表示给项目u的能量值加上v(0 <= v <= 100)。
如果cmd为1,那么接下来一个数u表示询问u相邻的项目的能量值之和。
所有点从1到n标号。
对每个询问,输出一行表示答案
参考AC代码
|
|
思路
对点的分块
轻点:对于边集小于sqrt(m)的点,我们就直接暴力去加周围的点就好了
重点:对于边集大于sqrt(m)的点,我们就只加与他相邻的重点和轻点对它的贡献
加边时 重点到轻点不需要连边 因为重点已经用sum在与他相邻的重点和轻点时已经算过了
这样我们每次查询的时候,如果查询的是轻点,我们就暴力扫一遍
如果查询的是重点,就输出目前的权值就好了