在线段树 query 操作中,我们通常会看到题解总有:
if (l > tree[u].r || r < tree[u].l) return;
但是经过我的发现,在我做过的所有线段树的题目中,将这条话去掉之后,没有任何死循环/WA的障碍。(?)
自认为正确实则不知道正不正确的证明:
假设线段树是 [1,n],当前节点为 u,当前区间为 [tree[u].l,tree[u].r],目标区间为 [L,R]。
显然,tree[1].l=1,tree[1].r=n。
我们发现,在一开始查找的时候,你一定是这样调用线段树的:
query(1, L, R);//从根节点开始,查询 [L,R] 区间
也就是说,一定有:tree[1].l<=L<=R<=tree[1].r
。
在我们每一次循环向下查找的时候,有:
if (L <= tree[u << 1].r) query(u << 1, L, R);
if (R >= tree[u << 1 | 1].l) query(u << 1 | 1, L, R);
也就是说,在访问 u×2 和 u×2+1 的时候,一定有 tree[u<<1].l∼r ∩ L∼R=∅ 且 tree[u<<1∣1].l∼r ∩ L∼R=∅。
所以以此类推,
if (l > tree[u].r || r < tree[u].l) return;
该语句不会被执行。