首页 > 其他分享 >分块一览

分块一览

时间:2024-02-27 18:23:59浏览次数:20  
标签:分块 int 一览 sqrt bl -- sq

前言

如题。

值域分块

顾名思义,就是在桶上分块。

它的用处是把区间修改和区间询问中某一种操作变成 \(O(1)\),另一种变成 \(O(\sqrt n)\)。

所以经常用来辅助维护两种操作数量严重不对等的数据结构。

典型代表有莫队和根号分治。

这里看一个莫队的例子。

如我们要维护一个二维数点。

那么莫队上的操作就是 \(O(n \sqrt n)\) 次单点加和 \(O(n)\) 次区间求和。

那么单点加时维护所属块的总和,就可以在区间查询时加速对于整块的查询而做到 \(O(\sqrt n)\) 查询。

具体代码如下:

void Add(int x){
	int bl=x/sq+1;
	if(x%sq==0){
		bl--;
	}
	cnt[x]++;
	block[bl]++;
}
void Del(int x){
	int bl=x/sq+1;
    if(x%sq==0){
		bl--;
	}
	cnt[x]--;
	block[bl]--;
}
int query(int x){
    int res=0;
	for(int i=0;i<=400;i++){
		if((i-1)*sq+1<=x&&x<=i*sq){
			for(int j=(i-1)*sq+1;j<=i*sq;j++){
                res+=cnt[j];
				if(j==x){
					return res;
				}
			}
		}
        res+=block[i];
	}
    return res;
}

根号重构

这个方法是用来维护诸如翻转之类的区间操作的。

首先你需要把所有点缩到一个块里。

然后对于每次操作,把操作两个端点从其所属块中断开(类似于珂朵莉树的搞法)。

然后这个问题就变成了整块下的问题。

那么现在就可以暴力去搞了。

但是注意到块很多的时候时间会退化到 \(O(n^2)\)。

所以当块的数量多余 \(\sqrt n\) 时,暴力重构所有块。

具体来说把所有块再次缩到一个块中。

这样保证了操作复杂度不会高于 \(O(\sqrt n)\)。

另外由于每次只会增加常数个块,所以重构数量是 \(O(\sqrt n)\) 的。

那么总复杂度也就只有 \(O(n \sqrt n)\)。

莫队二离

标签:分块,int,一览,sqrt,bl,--,sq
From: https://www.cnblogs.com/chifan-duck/p/17998335

相关文章

  • 分块和莫队
    1分块1.1概念简述分块被称为“优雅的暴力”。对于一个区间$[1,n]$,我们将其分成若干个块。在处理整块时直接维护整块信息,达到降低时间复杂度的目的。对于常规分块,设块长为$m$,则一般情况下$m$取$\sqrt{n}$时复杂度最优。下面举几例来说明分块如何降低时间复杂度。1.2......
  • 【学习笔记】分块学习笔记
    学习笔记索引分块经常听别人提起,我也学一下。正片分块就是将一个数列分成很多块,然后每块单独操作,最后的结果放到原数列里。分块的题目类型经常是区间中修改和查询。这里,一个长度为\(n\)的数列最多分成\(\sqrtn\)个块。先来看例题吧。例题P2357守墓人题目背景在一......
  • #分块,二分#洛谷 5356 [Ynoi2017] 由乃打扑克
    题目支持区间加和区间查询第\(k\)小分析分块之后给每个整块排序,这样修改的时候整块打标记,散块直接分开把需要加的部分暴力加之后归并,就是\(O(\sqrt{n})\)的查询的话,如果只有散块直接归并出结果,否则二分答案,加上小块合并成的整块,相当于是整体二分,就是\(O(\sqrt{n}\log{a_......
  • 分块
    分块前言在了解过树状数组和线段数之后,我们已经能处理许多区间的信息修改和查询的题目。但当信息不具有区间可加性时,用树状数组和线段树就不好处理了,这时候就可以用到一种优雅的暴力——分块。简介分块是一种思想,通过适当的划分,预处理一部分信息并保留,用空间换时间达到时空平......
  • 数论分块性质优化DP状态
    6311.mobitel给定一个r行s列的矩阵,每个格子里都有一个正整数。问如果从左上角走到右下角,且每次只能向右或向下走到相邻格子,那么使得路径上所有数的乘积不小于n的路径有多少条?对于100%的数据,1<=r,s<=300,1<=n<=10^6,矩阵中的数不超过10^6。so,一个普通的思想就是设f[......
  • P3870 分块题解
    这篇题解有点问题(分块标记处),但现在不想修,等有空修吧link分块是一种很神奇的暴力,学了它就会觉得什么都可以用分块做。分块的主要思想就是整块快速查询,散块暴力查询。比如说,分块可以在\(O(q\sqrt{n}+n)\)的时间复杂度内解决线段树模板题。回到本题,显然我们可以用每个块维护......
  • #根号分治,分块,dfs序#洛谷 7710 [Ynoi2077] stdmxeypz
    题目传送门分析首先把距离变成深度,用dfs序转成区间问题,考虑分块,散块直接改问题是整块,如果模数比较大,可以以深度为第一维下标差分标记,这样查询时就可以前缀和知道答案如果模数比较小,那么给该块打标记,查询时枚举模数即可,然后块长取1000,模数阈值取300,就能尽量减少时间代码#in......
  • #根号分治,分块#洛谷 5309 [Ynoi2011] 初始化
    题目传送门分析如果\(x\)比较大那么可以暴力修改,\(x\)比较小的话可以用数组打标记查询的时候对于暴力修改的部分可以分块,暴力修改的同时需要给块打标记如果\(x\)比较小的情况,一段区间相当于是中间很多段周期加上前后缀(当然可以直接区间减但是我被卡常了)我调的块长是160......
  • OxyPlot公共属性一览
    一、PlotModel1、构造函数中设置的属性publicPlotModel(){this.Axes=newElementCollection(this);//坐标轴集合;this.Series=newElementCollection(this);//线条集合;this.Annotations=newElementCollection(this);......
  • 莫队与分块
    【根号分治】例题:等差数列加给定一个长度\(n\)的数列,初始全都是0。(\(n\leq2\times10^5\))要求支持两种操作:\(1\;x\;y\;d\),表示把所有下标模\(x\)等于\(y\)的位置全部加上\(d\);\(2\;x\),表示查询\(a_x\)当前值。做法:对于所有\(x>\sqrtn\),我们直接暴力循环......