I have met the following line multiple times in some coders' code. Appreciated if anyone could tell me the meaning of this Macro?
#define ADDR(x, y) (((x) + (y)) | ((x) != (y)))
The following is an example of the codes from the internet that contains this macro. It looks like an implementation of some kind of balanced tree that claimed to have the ability to solve the problem of random query on k-th element in arbitrary sub-intervals of an fixed array in O(logn).
It looks like the ADDR macro is calculating some indexes of the intervals.
Is this macro some kind of trick? I also see this macro in the codes of other problems related to trees.
#include <bits/stdc++.h>
const int maxn = 2e5 + 10;
const int maxm = 2e6 + 10;
#define AVG(x, y) (((x) + (y)) >> 1)
#define ADDR(x, y) (((x) + (y)) | ((x) != (y)))
using namespace std;
struct SegTree {
int id, val;
} st[maxm], ss[maxn];
int lnum[maxm], lt[maxn], rt[maxn], tot;
bool cmp(const SegTree& a, const SegTree& b) { return a.val < b.val; }
void build(int l, int r, int start) {
int mid = AVG(l, r), p = ADDR(l, r), i, j, k = start, sum = 0;
if (l == r) {
st[start] = ss[l];
return;
}
lt[p] = tot;
rt[p] = tot + mid - l + 1;
tot += r - l + 1;
build(l, mid, lt[p]);
build(mid + 1, r, rt[p]);
i = lt[p];
j = rt[p];
while (i <= lt[p] + mid - l && j < rt[p] + r - mid) {
if (st[i].id < st[j].id) {
st[k] = st[i++];
lnum[k++] = ++sum;
} else {
st[k] = st[j++];
lnum[k++] = sum;
}
}
while (i <= lt[p] + mid - l) {
st[k] = st[i++];
lnum[k++] = ++sum;
}
while (j < rt[p] + r - mid) {
st[k] = st[j++];
lnum[k++] = sum;
}
}
int query(int l, int r, int ls, int rs, int k, int start) {
int mid = AVG(l, r), p = ADDR(l, r);
int i = ls > 0 ? lnum[start + ls - 1] : 0, j = lnum[start + rs];
if (l == r) return st[start].val;
if (j - i >= k) return query(l, mid, i, j - 1, k, lt[p]);
return query(mid + 1, r, ls - i, rs - j, k - j + i, rt[p]);
}