The next contest is after two weeks. Please add some contests before it.
№ | Пользователь | Рейтинг |
---|---|---|
1 | tourist | 3985 |
2 | jiangly | 3814 |
3 | jqdai0815 | 3682 |
4 | Benq | 3529 |
5 | orzdevinwang | 3526 |
6 | ksun48 | 3517 |
7 | Radewoosh | 3410 |
8 | hos.lyric | 3399 |
9 | ecnerwala | 3392 |
9 | Um_nik | 3392 |
Страны | Города | Организации | Всё → |
№ | Пользователь | Вклад |
---|---|---|
1 | cry | 169 |
2 | maomao90 | 162 |
2 | Um_nik | 162 |
4 | atcoder_official | 161 |
5 | djm03178 | 158 |
6 | -is-this-fft- | 157 |
7 | adamant | 155 |
8 | awoo | 154 |
8 | Dominater069 | 154 |
10 | luogu_official | 150 |
The next contest is after two weeks. Please add some contests before it.
2D Range minimum Query in <O(n*m*logn*logm),O(1)>
I solved THIS problem from "codechef June16 long challenge" by extending the " 1D RMQ sparse table method" to 2D version which finds maximum value in a submatrix in O(1) after O(n*m*logn*logm) preprocessing time.
Problem: Given an array[n] and Q queries. Each query asks for minimum in range x to y where 0=<x<=y<n
Preprocess : O(n*logn)
For(i=0;i<n;i++)
table[ 0 ][ i ]=array[ i ] //building base
For(j=1;j<=log(n);j++)
For(i=0;i+2^(j-1)<n;i++)
table[ j ][ i ] = min ( table[ j-1 ][ i ], table[ j-1 ][ i+2^(j-1) ] ) //use previously computed
we created a sparse table[ 1+logn ][ n ]
table[ j ][ i ] contains the minimum value in range i to i-1 + 2^j inclusive
Each range is a power of 2. First we build base of the table. Then for each range we split it into 2 equal parts for which value is already calculated. This way table is build in O(n*logn).
Query(x,y) : O(1)
len=y-x+1
k=log2(len)
return min(table[ k ][ x ],table[ k ][ y+1-2^k ]) // ranges may overlap
Query is then simply splitting the range in 2 parts each of which is a power of 2 and then using the pre-computed value from table. The 2 partitioned Ranges may overlap.
I found THIS video which explains it in detail
This was 1D RMQ. Now lets extend this concept to solve 2D RMQ
Problem:Given a matrix[n][m] and Q queries. Each query asks for minimum in submatrix[ (x1,y1), (x2,y2) ]
x1,y1 is the top left-most point and x2,y2 is bottom right-most point of the submatrix.Assume 0-based indexing
Preprocess : O(n*m*logn*logm)
Now,lets see how to code it
At First,for each row ir, we compute table[ 0 ][ ir ][ jc ][ ic ] ,the same as we did in 1D version.
Taking each row as an array and then computing its sparse table in same fashion as in 1D RMQ.
For(ir=0;ir<n;ir++)
{
For(ic=0;ic<m;ic++)
table[ 0 ][ ir ][ 0 ][ ic ] = Matrix[ ir ][ ic ];
For(jc=1;jc<=log2(m);jc++)
For(ic=0;ic+2^(jc-1)<m;ic++)
table[0 ][ir ][jc ][ic ] = min(table[0 ][ir ][jc-1 ][ic ],table[0 ][ir ][ jc-1 ][ ic+2^(jc-1) ])
}
The above step is nothing but computing the sparse table for each row.
The complexity for one row is O(m*logm) and so for all rows O(n*m*logm).
Now,we will use this base to build the entire table.
For(jr=1;jr<=log(n);jr++)
For(ir=0;ir<n;ir++)
For(jc=0;jc<=log(m);jc++)
For(ic=0;ic<m;ic++)
table[jr ][ir ][jc ][ic ] = min(table[jr-1 ][ir ][jc ][ic ],table[jr-1 ][ir+2^(jr-1) ][jc ][ic ])
Its not very difficult to understand this,just go through each line of the above code and try to visualise.
Clearly,the above step is O(n*m*logn*logm)
Query(x1,y1,x2,y2) : O(1)
We have to find the minimum in submatrix [(x1,y1),(x2,y2)]
lenx=x2-x1+1
kx=log2(lenx)
leny=y2-y1+1
ky=log2(leny)
First we will query on n
we have to query from row x1 to row x2.
But we have only computed for the range which are powers of 2 so we will divide in into two range
each of which is a power of 2.
x1 to x1-1+2^kx .....(say range R1)
x2+1-2^kx to x2 .....(say range R2)
The partition may overlap but that's not the problem here as we have to find the min/max only.
Now for each of the above two ranges R1 and R2, we have to query in column y1 to y2.
For this we will do the same range partition as we did above, i.e.
y1 to y1-1+2^ky ......(say range C1)
y2+1-2^ky to y2 ......(say range C2)
so query is simply 3 lines of code,
min_R1 = min ( table[kx ][x1 ][ky ][y1 ] , table[kx ][x1 ][ky ][ y2+1-2^ky ] )
min_R2 = min ( table[kx ][x2+1-2^kx ][ky ][y1 ], table[kx ][x2+1-2^kx ][ky ][y2+1-2^ky ] )
return min ( min_R1, min_R2 )
Done.
We can also use 2D segment tree to solve 2D RMQ in <O(n*m), O(logn*logm)>. It has a special benefit that we can also do update in O(logn*logm). We will see that in next blog.
1D RMQ Video
1D RMQ problem //use fats I/O
2D RMQ problems
problem1 // 2D segtree gives TLE in last subtask
problem2
Hello friends I would like to remind you that the registration is going to be closed soon. Register your team asap.
Название |
---|