区间处理之分块

分块这种思路很常见,就是把一个数列划分成k块,然后在块的基础上进行操作。

假如每块的大小为magic,那么长度为n的数列则一共会划分成ceil(n/magic)块。这样会有一些性质:

  1.原数列第i个的块号为i/magic,是块内的第i%magic个(不过这一条没有用)。

  2.假如i%magic==0,说明i是第i/magic块的起点,第i/magic块的范围是[i/magic, (i+1)/magic)。

下面是用分块思想对一个长为n的数列的操作:查找子区间的最大值和修改某个点的值。

 1 const int maxn = 50500;
 2 const int magic = 10;
 3 int n, q;
 4 int h[maxn], b[maxn];
 5
 6 void init() {
 7     for(int i = 0; i < n; i++) {
 8         if(i % magic == 0 || h[i] > b[i/magic]) {
 9             b[i/magic] = h[i];
10         }
11     }
12 }
13
14 int query(int l, int r) {
15     int ret = h[l];
16     for(int i = l; i <= r; ) {
17         if(i % magic == 0 && i + magic - 1 <= r) {
18             ret = max(ret, b[i/magic]);
19             i += magic;
20         }
21         else {
22             ret = max(ret, h[i++]);
23         }
24     }
25     return ret;
26 }
27
28 void update(int x, int v) {
29     h[x] = v;
30     int l = x / magic * magic;
31     int r = l + magic;
32     for(int i = l; i < r; i++) {
33         if(i % magic == 0 || h[i] > b[i/magic]) {
34             b[i/magic] = h[i];
35         }
36     }
37 }
时间: 2025-01-04 15:17:40

区间处理之分块的相关文章

poj 1141 Brackets Sequence 区间dp,分块记录

Brackets Sequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 35049   Accepted: 10139   Special Judge Description Let us define a regular brackets sequence in the following way: 1. Empty sequence is a regular sequence. 2. If S is a r

bzoj2002 弹飞绵羊 分块

这道题是分块的初尝试 讲给定的区间n进行分块处理 这个每次修改的复杂的只有logn 很方便 代码是学黄学长的 http://hzwer.com/3505.html 当然里面还是有一定我自己的想法在里面的 嫌我代码丑的可以去看黄学长的咯 #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<cstdlib> using namespace st

数据结构——分块

数据结构--分块 1.基本思想 ? 分块思想是通过适当地划分,预处理一部分信息并保存下来,用空间换取时间,达到时空平衡.事实上,分块比线段树等数据结构朴素得多,基本上算是"优化的暴力".但是它更加通用,且更易实现. ? 何为"适当的划分":玄学 数学方法推导 2.题型分析 1.数列分块 已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.求出某区间每一个数的和 对于100%的数据:N<=100000,M<=100000 显然这道题可以

bzoj 2038 小Z的袜子

好久没写题解了=_= ,整个暑假就没写过,还是决定写写吧,所以挑了这道大水题. 这是标准的莫队算法的问题,但由于可能数据水还是别的什么原因,不用曼哈顿最小生成树也可以过.具体就是按询问区间的左端点分块, 块内按右端点排序,然后暴力…… 真的是暴力,太暴力了,直到AC以后我才相信这么暴力真的可以在O(N^1.5)的时间复杂度内过掉. 块内具体就是右端点递增,左端点由于在块内并不是有序的,所以左端点就会晃来晃去,真是太暴力了…… 上代码: #include <cstdio> #include &l

cogs2264 魔法传输

2264. 魔法传输 ★★★   输入文件:magics.in   输出文件:magics.out   简单对比时间限制:1 s   内存限制:256 MB [题目描述] 自从看了<哈利波特>,小Y就十分渴望获得魔法值.于是他和一群向往魔法的孩子(当然这些孩子们都是不会魔法的)来到了哈利波特的家,大家坐成一排.哈利波特会不时的给大家传输魔法. 哈利每次会选择一个区间,给这个区间里的孩子们传输魔法:最左边的孩子给一点,第二个给两点--哈利有时会突然问你某一个孩子已经有了多少魔法. [输入格式]

AC日记——[国家集训队2010]小Z的袜子 cogs 1775

[国家集训队2010]小Z的袜子 思路: 传说中的莫队算法(优雅的暴力): 莫队算法是一个离线的区间询问算法: 如果我们知道[l,r], 那么,我们就能O(1)的时间求出(l-1,r),(l+1,r),(l,r-1),(l,r+1); 莫队算法怎么保证时间呢? 把询问排序; 然后进行暴力; 但是这样仍然需要很长很长的时间; 所以,我们引入一个根号方法,分块; 把区间的点分块; 然后每个询问的l,r按l所属的块为第一关键字,l,r为第二第三; 排序完后,就可以保证复杂度是O(n*sqrt(n));

【HDU 5145】 NPY and girls(组合+莫队)

pid=5145">[HDU 5145] NPY and girls(组合+莫队) NPY and girls Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 593    Accepted Submission(s): 179 Problem Description NPY's girlfriend blew him out!H

线段树普及版

一.简介线段树 \(ps\): 此处以询问区间和为例 线段树之所以称为"树",是因为其具有树的结构特性.线段树由于本身是专门用来处理区间问题的(包括\(RMQ\).\(RSQ\)问题等),所以其结构可以近似的看做一棵二叉查找树: \(emmmmm\)图是从网上偷的 对于每一个子节点而言,都表示整个序列中的一段子区间:对于每个叶子节点而言,都表示序列中的单个元素信息:子节点不断向自己的父亲节点传递信息,而父节点存储的信息则是他的每一个子节点信息的整合. 有没有觉得很熟悉?对,线段树就是分

数列区间询问中的分块思想

分块算法主要用于给定序列的区间询问问题,能够以较小的时间代价暴力求解,时间复杂度一般在O(n*n^0.5).关键在O(1) 维护好某一区间在增加或者减少一个边界元素所带来的影响.需要注意的就是在更新的区间的时候要先放大在缩小,否则可能出现当前区间左右边界互换的情况,这 个影响某一些题可能没有影响,但是极有可能出错. 时间复杂度:先考虑左边界的时间复杂度,由于分成了sqrt(n)块,而同一块中左标移动的范围最多是sqrt(n),那相邻块跳 转的情况呢?可以虚拟出每块中有至少一个询问进行思考,那么相