区间处理之分块
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了区间处理之分块相关的知识,希望对你有一定的参考价值。
分块这种思路很常见,就是把一个数列划分成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 }
以上是关于区间处理之分块的主要内容,如果未能解决你的问题,请参考以下文章