jzoj6424
在集训队作业 line 中,单调栈的限制很难处理。
但是顺着一个点往左边第一个比他大的点跳,则我们得到了可以转移的连续段。
考虑把一个点向左边第一个比它大的点连边,则形成了一棵树。
使用树链剖分+线段树即可维护。
回到此题。
求出一个点\(i\)向左/右跳到的第一个合法的区间位置\(l_i,r_i\)。
这可以使用一个栈求出。
先考虑栈顶的元素\(x\),如果\(l_i \leq x\leq r_i\),则显然\(x\)的\(l,r\)可以用于更新\(i\)的\(l,r\)。
然后把\(x\)插入栈中。
发现\(x\)的区间一定包含了栈顶元素的区间,所以栈顶的元素不会对后面的产生影响,可以弹出。
这保证了时间复杂度。
然后考虑把一个点\(i\)向\(l_i\)连边,则形成了树。
这棵树上一个点向父亲跳即可找到以它为右端点的合法区间。
那么一个询问显然答案就是两个点的\(lca\)的深度。