A:
考虑如果现在在点 i,能否走到编号更小的点。如果可以,那么必然存在一个 j≥i>aj 使得你可以走到点 aj。
那么我们对于每个 i,将区间 (ai,i] 加一,从 x 开始能走到的编号最小的点也就是 x 左侧最近的 0 的位置。
带修问题可以直接用线段树维护,查询的时候使用线段树二分。
时间复杂度 O((n+q)logn) 。
B:
由于一个棋子的两条路径无交且包含所有的边,所以对于每条边,每个棋子恰有其中一条路径包含它。
那么我们枚举其中一条边,要求所有棋子均经过它,那么所有棋子的路径选择方案就确定下来了。
多条边能同时在答案中当且仅当它们确定的方案一致,即每条边对应一个选择方案,需要选出最大的等价类。判断等价关系直接使用随机异或哈希即可,时间复杂度 O(mlogm)。
C:
设外层、内层子序列分别为 S={p1,p2,…,pl1},T={q1,q2,…,ql2}。
原先一层的情况下,我们可以要求 ∀j∈(pi−1,pi),aj=api ,即钦定一种子序列在最左的出现位置处统计到。
那么两层的情况下,我们考虑对内层进行 DP,设 fi 表示考虑到 i 且钦定 i 在 T 内的答案,那么枚举 T 中上一个位置 j ,考虑 (j,i) 中的数填入 S 的方案数,有如下限制:
- 对于 j<p<i,ap=ai,要求 p 不能在 S 中。
- 令 l 为最大的 j<p<i 使得 ap=ai,必须存在 l<q<i 使得 q 在 S 中。
- 对 S 中每相邻两个数 p,q,要求 ∀k∈(p,q),ak=aq 。
其中第一条限制是为了限制 T 为 S 中最左的,后两条限制是为了限制 S 为最左的。
时间复杂度 O(n2),空间复杂度 O(n) 。
D:
摆了。
对于一个数 v,取出最长的相邻两项和 ≤v 的子序列,如果其长度 ≥k 那么答案就 ≤v 。
我们把 2ai≤v 的数称为「小数」,反之称之为「大数」。小数必定可连选,大数必定不可连选。
最优情况必定为小数全选,对于每相邻两个小数,如果它们之间最小的大数可选就选上。
那么我们按值域从小到大做扫描线,每次会将一些大数切换为小数。注意到相邻的小数之间显然均为大数,所以求出若干四元组 (i,j,l,r) 表示在 v∈[l,r] 时 i,j为相邻小数且对答案有 1 的贡献。
差分为对 v≥l 的单点加矩形求和,还需注意 [i,j] 跨过端点时的贡献。
对这些四元组以及询问进行整体二分即可。
时间复杂度 O((n+q)log2n),可以通过。
然而还可以继续优化!对于一个时刻 v,仍有贡献的四元组 (i,j,l,r),l≤v≤r 的区间 [i,j] 除端点外互不相交,那么数点可以降一维:只要求 i 在区间内,此时只会算多包含右端点的一个贡献区间。
前驱后继可以类似地在整体二分中双指针维护,时间复杂度 O((n+q)logn) 。