本文同步发表于 https://www.zybuluo.com/Gary-Ying/note/1288518 线段树的小应用 -- 维护区间开方区间求和 题目传送门 约定: sum(i,j) 表示区间 [i,j] 中所有元素的和,也就是\(\Sigma_{k=i}^j a_k\) 这个维护思想来自 分块 :线段树维护区间开方的难点就在于我们没有办法很方便地维护区间的和,具体来说,如果我们对区间 [l,r] 进行开方,我们并不能从 sum(l,r) 推到 sum'(l,r). 这就比较麻烦了,我们…
题解:区间开方emmm,这马上让我想起了当时写线段树的时候,很显然,对于一个在2^31次方以内的数,开方7-8次就差不多变成一了,所以我们对于每次开方,如果块中的所有数都为一了,那么开方也没有必要了. 所以开个tag标记一下当前块是否均为一,如果不是的话每次暴力构块即可 代码如下: #include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorit…
题目链接:https://loj.ac/problem/6281 参考博客:https://blog.csdn.net/qq_36038511/article/details/79725027 我一开始看到开方有点懵,看了上面的博客说2^31差不多5次开方就快变成1了,可以开标记数组,于是按照这个思路写了下,然后就过了,看来以后还要多看题意分析数据. 代码: #include<iostream> #include<cstring> #include<cmath> #in…
题解:分块的区间求和比起线段树来说实在是太好写了(当然,复杂度也高)但这也是没办法的事情嘛.总之50000的数据跑了75ms左右还是挺优越的. 比起单点询问来说,区间询问和也没有复杂多少,多开一个sum数组记录和,加的时候非完整块暴力重构,完整块加整块.查询时非完整块暴力加,完整块加整块 代码如下: #include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include&l…
题目链接 int内的数(也不非得是int)最多开方4.5次就变成1了,所以还不是1就暴力,是1就直接跳过. #include <cmath> #include <cstdio> #include <cctype> #include <algorithm> #define gc() getchar() typedef long long LL; const int N=5e4+5; int n,size,bel[N],A[N]; LL sum[N]; inli…
水一道入门分块qwq 题面:传送门 开方基本暴力.. 如果某一个区间全部都开成1或0就打上标记全部跳过就行了 因为一个数开上个四五六次就是1了所以复杂度能过233~ code: //By Menteur_Hxy #include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #include<cmath> using namespace std; int rd()…
题解:感谢hzwer学长和loj让本蒟蒻能够找到如此合适的入门题做. 这是一道非常标准的分块模板题,本来用打标记的线段树不知道要写多少行,但是分块只有这么几行,极其高妙. 代码如下: #include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; ],a[],lump[]; int n,sz…
 题解:非常高妙的分块,每个块对应一个桶,桶内元素全部sort过,加值时,对于零散块O(sqrt(n))暴力修改,然后暴力重构桶.对于大块直接整块加.查询时对于非完整块O(sqrt(n))暴力遍历.对于完整的大块用lower_bound或者手写二分log(sqrt(n)查找,总复杂度O(n*sqrt(n)*log(sqrt(n))) 代码如下: #include<cmath> #include<vector> #include<cstdio> #include<c…
题解:自然是先分一波块,把同一个块中的所有数字压到一个vector中,将每一个vector进行排序.然后对于每一次区间加,不完整的块加好后暴力重构,完整的块直接修改标记.查询时不完整的块暴力找最接近x的解,完整的块用二分查找,其实还可以用set维护,出于对最暴力AC的尊敬,我并没有这么写.照样过了. 代码如下: #include<cmath> #include<cstdio> #include<vector> #include<cstring> #inclu…
题目链接 \(Description\) 给出一个长为n的数列,以及n个操作,操作涉及区间询问等于一个数c的元素,并将这个区间的所有元素改为c. \(Solution\) 模拟一些数据可以发现,询问后一整段都会被修改,几次询问后数列可能只剩下几段不同的区间了. 那么还是暴力,每个块维护的是整个块是否仅被一种权值覆盖.查询时对于相同权值的块就可以O(1)统计:否则暴力统计并修改答案:不完整的块暴力. 这样看似最差情况下每次需要O(n)的时间,但实际远远到不了 假设初始序列都是同一个值,那么查询需要…