Divide & Conquer - SRQ
Authors: Benjamin Qi, Andi Qu
Prerequisites
Using Divide & Conquer to answer offline or online range queries on a static array.
Static Array Queries
Focus Problem – read through this problem before continuing!
Given a static array , you want to answer queries in the form
where denotes an associative operation.
In the prerequisite module, it was shown that we can get time queries with time preprocessing when denotes min
. But how do we generalize to other associative operations?
We can use divide & conquer to answer queries offline in time or online in .
Offline Queries
Suppose that all queries satisfy (initially, and ). Letting , we can compute
for all and
for each . Then the answer for all queries satisfying is simply due to the associativity condition. After that, we recurse on all query intervals completely contained within and independently.
The code below should work if min
is replaced by any associative operation.
Warning!
Be careful to combine elements in the appropriate order if the operation is not commutative.
Solution - RMQ
1int n,q,A[MX],B[MX];2vi x, ans;3int lef[MX], rig[MX];45void divi(int l, int r, vi v) {6 if (!sz(v)) return;7 if (l == r) {8 trav(_,v) ans[_] = x[l];9 return;10 }
Online Queries
We do the same thing as above, except we store all computes values of lef
and rig
within a 2D array using memory, similarly as sparse table.
Resources | |||
---|---|---|---|
Benq | implementation |
Solution - RMQ
In the code below, dat
performs the roles that both lef
and rig
do in the previous solution. Let comb(l,r)
equal . For example, if and we only consider levels and then we get
dat[0][i]=comb(i,9)
fori
in[0,9]
dat[0][i]=comb(10,i)
fori
in[10,19]
dat[1][i]=comb(i,4)
fori
in[0,4]
dat[1][i]=comb(5,i)
fori
in[5,9]
dat[1][i]=comb(i,14)
fori
in[10,14]
dat[1][i]=comb(15,i)
fori
in[15,19]
mask[0..4]=0
mask[5..9]=2
mask[10..14]=1
mask[15..19]=3
Examples of queries:
- To query
comb(0,16)
we first count the number of training zeroes inmask[0]
XORmask[16]
, which is0
. So our answer ismin(dat[0][0],dat[0][16])
. - To query
comb(12,18)
we first count the number of training zeroes inmask[12]
XORmask[18]
, which is1
. So our answer ismin(dat[1][12],dat[1][12])
.
1int n,q;2vi x, ans;34int dat[18][MX], mask[MX]; // 18 = ceil(log2(n))56void divi(int l, int r, int lev) { // generate dat and mask7 if (l == r) return;8 int m = (l+r)/2;9 dat[lev][m] = x[m];10 ROF(i,l,m) dat[lev][i] = min(x[i],dat[lev][i+1]);
A data structure known as sqrt-tree can speed up preprocessing time and memory to .
Problems
Status | Source | Problem Name | Difficulty | Tags | Solution | URL |
---|---|---|---|---|---|---|
JOI | Easy | |||||
CC | Easy | Check CC | ||||
Baltic OI | Normal | |||||
DMOJ | Normal | Check DMOJ | ||||
Plat | Hard | External Sol |
Module Progress:
Join the USACO Forum!
Stuck on a problem, or don't understand a module? Join the USACO Forum and get help from other competitive programmers!