LCA 上课思考题合集

这里应该有一段前言,但是我不知道写啥。

大鱼吃小鱼

有一排 \(n\) 条鱼,每条鱼有一个体型值(正整数)\(a_i\),一条鱼可以吃掉相邻的鱼,如果被吃的鱼体型小于等于自己。吃完后自己的体型会加上被吃的鱼的体型。鱼之间位置的先后顺序不变。

问题 1

每条鱼最多可以吃到多大的体型?

原题

  • \(O(n \log n \log V)\):每次可以先向一个方向二分到一个最长的最大值不大于自己的区间,然后一口气全部吃掉,另一边做同样的操作。如此循环往复。以后这样每进行两次体积至少会翻倍(因为吃掉了一个原来比自己体积大的鱼),复杂度就是 \(O(n\log n \log V)\) 的。

  • \(O(n)\):一个区间的最大值一定可以吃掉区间内的所有数。可以按区间最大值把区间分成两段,就是笛卡尔树。自上而下对笛卡尔树 DFS。一条鱼肯定能吃掉笛卡尔树上对应的子树。这时将它子树的权值和与它的父亲(就是两个方向第一个比它大的中较小的那一个)的体积比较,如果小于父亲就寄了,否则范围和父亲相同,直接自上而下递推即可。

  • \(O(n)\; \text{Another}\):设一条鱼能吃到的区间是 \([L_i,R_i]\),那么 \(\forall j \in [L_i,R_i]\)\([L_j,R_j] \subseteq [L_i,R_i]\)。可以尝试暴力 DFS 解决:一开始将所有 \([L_i,R_i]\) 设为 \([i,i]\),每次向左或向右扩展,如果能吃掉,并且已经求得了该点的答案区间,那么直接并上;否则递归求解该点即可。每个点只会扩展一次,复杂度 \(O(n)\)

问题 2

单点修改 \(a_i\),区间查询 \([l,r]\) 内有多少条鱼可以吃完区间内其它所有鱼。(只有这个问题有修改和查询)。

原题

带单点修改,区间查,想到线段树(问号

线段树维护结点 \([l,r]\),显然如果一个点对应的 \([L_i,R_i]\)\([l,r]\) 完全包含的话,那么 \(i\) 肯定没戏。否则如果 \(L_i = l\) 或者 \(R_i = r\) 的话,鱼还有机会吃掉外面的区间再吃回来。于是对于区间 \([l,r]\),一条鱼可能产生贡献的有效的扩展区间一定是一段前缀或者后缀。

更精细地,考虑从左向右吃鱼的过程,每次被挡住都是因为出现了一条体积更大的鱼,体积是一次一次翻倍的。一个区间的扩展过程中最多会出现 \(\log V\) 种不同的前缀或后缀。对每个线段树节点暴力维护 \(\log V\) 种等价类对应的鱼的个数即可。区间合并时双指针维护,时间复杂度 \(O(n\log n \log V)\)

问题 3

如果我们有一种道具,鱼每用一次道具可以吃掉任意一条相邻的鱼,无视体型,请你对于每条鱼求出,它吃完所有其它鱼最少需要多少个道具。

  • \(O(n \log n \log V)\):按照问题 1 的暴力思路,我们每次走不动时,直接无脑选择两边障碍种体积大的那一个使用道具即可。因为吃了大的小的也能吃下去了。且这样做体积也一定翻倍,复杂度不变。

  • \(O(n \log n)\):按问题 1 的搜索思路,搜完一遍求出不用道具的答案,再每个区间使用一次道具,再暴搜一遍,如此重复 \(\log V\) 次就可以(?。

  • \(O(n)\):笛卡尔树。若能吃掉父亲则继承父亲的答案,否则变成两边中体积更大的那一个的答案加一(可以单调栈求出)。

问题 4

如果我们把吃鱼的规则改为只能吃右边(编号更大)和自己相邻的鱼(道具不受影响),问题 2 和 3 的结果会有什么变化?(你不能先操控别的鱼吃鱼,再用道具吃它)

不是很懂题意欸,都说一下吧。

  • 要全吃完

    • 问题 2:只有左端点能全走完,暴力即可。

    • 问题 3:用道具先把左边全吃完,然后暴力向右扩展。

  • 只吃完右边就行

    • 问题 2:线段树暴力维护合法的鱼的集合。合并时右儿子肯定全部保留。左儿子要扔掉一段后缀。用一些数据结构维护这个东西就行(?

    • 问题 3:还可以用道具吃左边。吃的左边的鱼是一个连续段,这个答案不单调也是凸的。可以二分/三分。

问题 5

如果我们允许小鱼吃大鱼,也就是定义常数 \(k (k \ge 0)\),将题目条件改为“一条鱼可以吃掉相邻的鱼,如果被吃的鱼体型小于等于自己的体型加 \(k\)”,问题 3 的结果会有什么变化?

和问题 3 基本相同。条件甚至更松了。采用上述任一做法即可。

问题 6

如果我们去掉问题 5 中的 \((k \ge 0)\) 的限制,问题5的结果会有什么变化?

看似和问题 5 很像,实际上还是有一些问题。问题在于当前的和 \(S < k\) 时,每次吃鱼没有翻倍的性质,而且面临着决策的问题:有可能向左还是向右使用道具都不能顺便吃掉另一边。

但是问题都出在 \(S < k\) 的位置,当 \(S \ge k\) 时,每操作两次 \(S - k\) 都会翻倍,且不会面临决策问题。

注意到 \(S < k\) 时只能通过道具长大。所以考虑用一些方式维护从 \(S < k\)\(S \ge k\) 的变化过程。双指针,对每个左端点,找出最小的右端点,使得这段区间内的和 \(\ge k\)。那这段区间内的所有鱼就可以通过道具将区间内的所有鱼吃掉来成长到 \(k\),用方法 3 的暴力套路求解答案并更新即可。时间复杂度 \(O(n \log n \log V)\)

\(5 \times 10^6\) 的数据范围,显然无法通过。考虑套用方法 3 的更低复杂度做法。但是这有些困难。于是考虑直接优化上面的暴力。

这个时候我们的 diandian2020 大神就提出了下面的方法:

倍增值域分块,将 \([2^i,2^{i+1})\) 的值分为一块。对第 \(i\) 块维护第 \([i,\infty)\) 块的所有值的桶,然后算出每个位置的前驱后继。设当前总和为 \(S\),吃掉的区间为 \([l,r]\);维护 \(S - k\) 的值,设 \(S - k\) 在第 \(b_i\) 个块内,每次找出在 \([b_i,\infty)\) 块中 \(l\) 的前驱和 \(r\) 的后继扩展即可。这样最劣也可以找到一个 \(\ge \dfrac{1}{2}S\) 的值,\(S - k\) 每次至少变成原来的 \(\dfrac{3}{2}\) 倍。时间复杂度还是 \(O(n \log V)\)。空间复杂度 \(O(n\log V)\),但是因为 \(S - k\) 在不断增大,只要逐块处理扫一遍即可。空间 \(O(n)\)

下面是 LCA 的 \(O(n)\) 题解:

题目中 \(a_i\) 表示鱼的体型,\(n\) 表示总数。

首先,任何时候鱼的状态一定是“吃完了一个区间位置中的所有鱼”。并且鱼的体型一定等于区间内鱼的初始体型之和。所以我们用这个区间来表示鱼的状态。以下,将区间内的鱼的体型之和简称为区间和。

我们称:

  • 一个无法不用道具扩展的区间是自闭区间。(我们规定 \([1,n]\) 也是)
  • 区间和 \(\ge k\) 的区间是大鱼区间
  • 区间和 \(\le k\) 的区间是小鱼区间

显然,小鱼区间是不可能不用道具去吃任何鱼的(因为鱼的体型都非负)。

我们考虑任何一个鱼从初始吃完所有鱼的过程。这个过程中鱼的体型显然是单调不降的,存在一个时刻第一次变成大鱼,在这之前必然每一步吃鱼都要用道具。(或者可能整个序列都是小鱼,这种情况下答案为 \(n-1\)。这种情况要特判。)我们从这个时刻把一个方案分成前后两段:

  • 从最开始到第一个大鱼区间:使用道具次数是大鱼区间的长度减 \(1\)。容易证明这第一个大鱼区间一定是序列上固定某个左端点或者右端点前提下的极短大鱼区间,不超过 \(2n\) 种。因此只要双指针预处理出这些极短大鱼区间,想办法求出每个极短大鱼区间在后半段的最小道具数,再用单调队列更新每个 \(i\) 的答案即可。
  • 从第一个大鱼区间到整个序列。剩下的问题是求出每个极短大鱼区间在后半段的最小道具数。

如果两个自闭区间相交但互不包含,可以证明它们的交集部分一定是小鱼区间。(否则,我们设它们按位置顺序是 \(A−b−C−d−E\),其中 \(b,d\) 是单条鱼,\(A,E\) 可以为空,\(C\) 不为空,两个自闭区间分别是 \(A−b−C\)\(C−d−E\)。则,按自闭的定义有 \(d>A+b+C−k,b>C+d+E−k\)。如果 \(C \ge k\) 就有 \(d>A+b\ge b>d+E\ge d\),矛盾。)

另外,容易证明一个自闭的大鱼区间下一步用道具吃的一定是两侧相邻的鱼中体型较大的,因为吃了较大的那个后体型一定足够立刻吃较小的,这总是更优。

所以对于一个大鱼区间,所有包含它的自闭区间必然组成区间套,并且方案选择是固定的。

另外,这也容易证明大鱼自闭区间的总数不超过 \(2n\) 个。我们考虑把一个大鱼自闭区间关联到它两侧相邻的鱼中较小的那个上,容易证明每个鱼在每一侧最多会被一个大鱼自闭区间关联。(\(a−B−c−D\),容易证明不可能有 \(B\)\(B−c−D\) 都是大鱼自闭区间且有 \(a≤c\)。否则 \(B+c+D \ge B+a+D>B+(B+c+D−k)+D \ge B+(k+c+D−k)+D=B+c+2D\),矛盾)

现在问题有两个:

  1. 如何求出所有的大鱼自闭区间。

  2. 如何求出每个大鱼自闭区间扩展到全序列的最小操作次数(以下简称扩展到全序列的最小操作次数为“答案”)。

  3. 对于第一个问题,我们考虑分别对于每个位置求出每一侧与他相关联的那个大鱼自闭区间(若存在)。我们考虑从左往右枚举 \(i\),并用双指针维护以 \(i-1\) 为右端点的极短大鱼区间记为 \([L_i−1,i−1]\),并在 \(i\) 增加过程中维护 \(L_{i−1}−1\) 左侧所有的点集 \(S\) 中可能成为左相邻点的,试图求出以 \(i-1\) 为右端点且关联到 \(i\) 的大鱼自闭区间。那么:

  4. \(S\) 中,一个下标、体型都小的位置必然从当前 \(i\) 开始都永远不可能是(大鱼自闭区间的)左相邻点。所以我们首先用单调栈维护 \(S\),只保留那些体型后缀最大的位置。

  • \(S\) 中,每次我们要查询 \(\ge a\) 的最小鱼并判断,只有这条鱼和 \(i\) 有可能构成大鱼自闭区间。但是我们可以注意到,\(S\) 中那些 \(\ge a_i\) 的鱼对于更大的 ii 也不可能是大鱼自闭区间的左相邻点(因为 \(\sum a[L_{i−1},i−1]+ai \ge k+ai\) 就已经足够吃它了),所以我们这个查询直接在单调栈上删除元素即可。(注意有一种边界细节是,大鱼自闭区间是整个序列的前缀或后缀,\(S\) 删空了。)

  • \(i\) 增大的时候 \(L\) 右移,新增的元素在单调栈里维护即可。

从左到右、从右到左分别做一遍这个过程就解决了第一个问题。

对于第二个问题,我们不妨设 \(f([l,r])\) 表示区间 \([l,r]\) 的答案。显然有 \(f([1,n])=0\)。然后对于一个大鱼自闭区间 \([l,r]\),按前文有 \(f([l,r])=f(M([l−1,r]))+1\)(当 \(a_l−1 \ge a_r+1\))或者 \(f([l,r])=f(M([l,r+1]))+1\)(当 \(a_l−1<a_r+1\)),其中 \(M\) 表示包含这个区间的最小自闭区间。(按前文引理,包含一个大鱼区间的最小自闭区间是唯一的。)

所以我们只要查询出所有这些 \(M\) 然后递推计算就行了。用扫描线+单调栈处理一遍所有大鱼自闭区间即可求出所有需要的 \(M\)

前面所有步骤都是 \(O(n)\),所以这个问题的时间复杂度是 \(O(n)\)

问题 7

如果我们把问题5和6中的条件从差值改成比例,也就是定义常数 \(c(c>0)\),将题目条件改为“一条鱼可以吃掉相邻的鱼,如果被吃的鱼体型小于等于自己的体型乘 \(c\)”,问题5和6的结果会有什么变化?

  • \(c \ge 1\):同问题 5。

  • \(c < 1\) 暂时没想到合适的做法(

问题 8

尝试找到一个有意思的问题并改编一个 OI 题目。例如:如果我们把鱼放到树上,定义每条鱼占据一个树上连通块,两条鱼相邻当且仅当占据的连通块相邻,初始每条鱼占据一个点,被吃的鱼的连通块会被吃它的鱼占据,会发生什么?

咕咕咕。

循环博弈

\(n\) 个人在玩游戏,有一堆初始总数为 \(m\) 的石子,从第 \(1\) 个人开始轮流取,每次每个人需要拿走至少 \(1\) 个至多 \(k\) 个石子。如果轮到一个人时石子没有了,游戏结束。定义游戏的结果为游戏结束时轮到的人的编号。

现在有一个 \(n\)\(n\) 列的矩阵 \(A\),其中 \(A_{i,j}\) 表示如果游戏结果为 \(i\),第 \(j\) 个人会获得 \(A_{i,j}\) 的收益。保证 \(A\) 每一列的元素互不相等,不妨设 \(A\) 的每一列都是 \(1\)\(n\) 的排列。

每个人都想最大化自己在游戏结束后的收益,他们也知道所有人都这么想。

问题 1

讨论里所有人都最大化自己的收益在实际游戏中会怎么决策,说明每个人有确定的决策。

(并不是所有博弈都有符合直觉的确定的最优策略。例如,在一些多人游戏中经常发生某个人已经必败了但他可以选择其它人谁赢。这时你不能仅凭每个人都最大化自己收益来确定他的选择。)

一个局面显然可以直接用轮到谁和还剩几个石子直接刻画。状态之间形成 DAG,不成环且因为 \(A\) 的每一行是排列,所以每个人的最优决策是唯一的。

问题 2

给出一个关于 \(n,m,k\) 的多项式时间的算法求出最优策略。

定义 \(f(x,y)\) 表示轮到第 \(x\) 个人且石子还剩 \(y\) 个时,所有人都采取最优策略的情况下游戏的结果。

\(f(x,y)[i]\)\(f(x,y)\) 对应的局面第 \(i\) 个人获得的收益。

直接暴力递推即可。

\[f(x,y) = \max_{z=y-k}^{y-1} f(x + 1,z)[x] \]

问题 3

证明 \(f\) 关于石子个数存在周期。换言之,存在正整数 \(T\) 使得不满足 \(f(x,y)=f(x,y+T)\) 的正整数 \((x,y)\) 只有有限多对。

可以直接搞一个非常松的上界。

\(f(*,y)\) 只能由 \(f(*,z)[z \le y \land z \ge y - k]\) 推出来。上式只有 \(n^{n \times k}\) 种取值。根据鸽巢原理,一定会有周期。

问题 4

考察 \(n \le 3\)\(f\) 的情况。例如考虑:不满足周期的最大数对的上界是多少?最小正周期的上界是多少?如何构造?\(f(1,*)\)\(f(2,*)\) 两列值有什么关系?(将 \(k\) 视为参数)

在此基础上提出一个尽可能高效的算法计算 \(n \le 3\) 时的这个问题。

打表解决问题。

\(n = 3\) 时:

\(k\) 最小正周期的上界 不满足周期的最大数对的上界
\(1\) \(3\) -
\(2\) \(5\) \(11\)
\(3\) \(7\) \(12\)
\(4\) \(9\) \(15\)
\(5\) \(11\) \(18\)
\(6\) \(13\) \(21\)
\(7\) \(15\) \(24\)
\(8\) \(17\) \(27\)
\(9\) \(19\) \(30\)

规律十分显然,一个是 \(2k+1\),一个是 \(3k+3\)

怎么构造呢?打表结果:

最小正周期取到上界的所有 \(A\)(与 \(k\) 无关)

1 2 3 
3 1 2 
2 3 1

1 3 2 
3 2 1 
2 1 3

2 1 3 
1 3 2 
3 2 1

2 3 1 
1 2 3 
3 1 2

3 1 2 
2 3 1 
1 2 3

3 2 1 
2 1 3 
1 3 2

都长得很像,暂时还没能更好的刻画。

不满足周期的最大数对取到上界的所有情况:

1 1 3 
2 3 2 
3 2 1

1 3 2 
3 1 1 
2 2 3

3 2 2 
2 1 3 
1 3 1

另外,进入周期前最多进行 \(O(k)\) 轮,\(n \le 3\) 时,用单调队列优化感觉可以做到 \(O(nk)\),暂时没想到更好的做法。

问题 5

现在取消对 \(n\) 的限制,考察 \(f\) 的最小正周期和非周期部分的上界,并给出使之渐进尽量大的构造。(将 \(n,k\) 视为参数)

完全不会呀。

事已至此,先打表吧。

\(n = 4\) 时:

\(k\) 最小正周期的上界 不满足周期的最大数对的上界
\(1\) \(4\) -
\(2\) \(7\) \(27\)
\(3\) \(10\) \(28\)
\(4\) \(13\) \(33\)
\(5\) \(16\) \(40\)
\(6\) \(19\) \(47\)
\(7\) \(22\) \(54\)
\(8\) \(25\) \(61\)
\(9\) \(28\) \(68\)

这回两个值分别是 \(3k+1\)\(7k+5\)。(\(k \le 3\) 不满足)。

实际上经过上面打表,关于周期,我们还有更强的结论:

最小正周期的取值只有 \(1,k+n-1,2k+n-2, \cdots,(n-1)k+1\)

感性上很对,具体原因我也解释不清楚。

关于 \(n = 5\),我猜了一下答案矩阵的形态,得到了这样的结果:

\(k\) 最小正周期的上界 不满足周期的最大数对的上界
\(1\) \(5\) -
\(2\) \(9\) \(113\)
\(3\) \(13\) \(113\)
\(4\) \(17\) \(127\)
\(5\) \(21\) \(140\)
\(6\) \(25\) \(164\)
\(7\) \(29\) \(188\)

最后公差是 \(24\),没什么规律(?

继续题面部分:这个问题比较困难,所以我们给出一些提示。另外,不要忘记打表观察也是一种方法。

混循环数列不容易处理,我们考虑纯循环,也就是说,令 \(g(x,y)\) 是一个函数对任意整数 \(y\)\(1 \le x \le n\) 都满足 \(g(x,y)=g(x,y+T)\) 且存在 \(M\) 使得 \(\forall y>M,g(x,y)=f(x,y)\)。研究 \(g\) 也可以得到循环节的性质。

例如:记 \(g_x\) 表示数列,\(g_x[y]=g(x,y)\)(下标 \(y\) 是包括负数在内的全体整数)。考虑:

问题5.1:\(g_x\)\(g_{x \bmod n} + 1\)
两个数列之间有什么递推关系?

问题5.2:根据 5.1 的递推关系,如何直观刻画 \(g_x\) 更方便?

问题5.3:我们不妨设 5.1 的递推关系为 \(g_x = P(g_{x \bmod n + 1})\),那么我们知道 \(P^n(g_x) = g_x\),也就是 \(P^n = I\) 作用是保持不变,尝试通过 \(P^n\) 的这一性质来研究周期的性质。

问题5.4:我们不妨设原本的序列也有规则相同(但定义域不同)的递推 \(f_x = P(f_{x \bmod n + 1})\),尝试通过 \(P\) 反复迭代过程中 \(f\) 的变化过程研究非周期部分的上界。

不去想打表了。尝试严谨证明上面关于周期的结论:

首先最后所有人都只能选一种决策时,周期为 \(1\)

只考虑 \(g_x\) 就是 \(f_x\) 的循环部分。这样问题就简化了很多。我们不去想 \(g_x\) 是如何递推出来的,而是去考虑它们之间的关系。考虑 \(g_x\) 中的连续段。因为形成了周期,所以连续段只会变大或者变小,不会消失,也不会有新的连续段产生。

现在只考虑连续段之间的分界点。设分界点为 \(p\)

\(g_{x \bmod n + 1,p} = z\)\(g_{x \bmod n + 1,p + 1} = w\),若 \(z\) 对于 \(x\) 来说优于 \(w\),那么 \(g_{x,p+1}\)\(g_{x,p+k}\) 一定不劣于 \(z\),即优于 \(w\),然而连续段不会消失,因此 \(g_{x,p+k+1}\) 一定为 \(w\),分界点 \(p\) 增加了 \(k\)

\(z\) 劣于 \(w\),则 \(g_{x,p+2}\) 一定不劣于 \(w\),然而 \(z\) 不会消失,因此 \(g_{x,p+1}\) 一定为 \(z\),此时 \(p\) 向右移动 \(1\)

一个分界点移动 \(n\) 次,周期一定为 \((n - i)k + i\)。然后因为是周期,所以不同分界点的 \(i\) 一定相同。符合打表结论。

注意 \(i\) 不能等于 \(0\)\(n\),此时会出现 \(n\) 种情况之间都是一种关系,从而推出自己大于自己的矛盾结论。

问题 6

找到原问题的一个真正的多项式时间算法,也就是关于输入长度的多项式,即使 \(m,k\) 是高精度的。给出你算法的时间复杂度上界。

问题 7

问题7:研究这个问题的一些特殊情况或拓展情况,并尝试出题。例如:如果我们规定矩阵 \(A\) 的值是 \(A_{i,j} = (i + j - 2) \bmod n + 1\) 会发生什么?如果 \(k = \infty\) 会发生什么?如果 \(A\) 的一列内有多个相同数字,会对最优策略的概念产生什么影响?

\(k = \infty\) 时,打表/感性理解可以得出,每个人的决策都没什么变化。所以最后周期会变成 \(1\)。(其实就是长为 \(\infty\) 的连续段)。

其他的有点抽象。

如果 \(A\) 的一列内有多个相同数字,那就没有所谓最优决策了(照应问题 1),可以钦定一些人是仇人,要最小化仇人的效益(笑。

全局平衡

你有 \(n\) 个数 \(a_1,a_2, \cdots ,a_n\) 。现在你要构造出一棵 \(n\) 个叶子的有根二叉树,把这些数分别填入每个叶子。定义一个叶子走到根的代价等于它填的数加上到根距离。(树没有边权)

你希望让所有叶子走到根的最大代价尽可能小,并求出这个最小值。

问题 1

假如这些数是 $ n/x $ 个 $ x $ 和 $ n - n/x $ 个 1($ x $ 是一个参数),你能求出问题答案大致的大小吗?

\(x > 1\)。若同一种数的层数极差 \(\ge 2\) 一定不优,因此 \(x\) 一定都分布在 \(\log \dfrac{n}{x}\) 层级别的位置。对答案的贡献为 \(x + \log \dfrac{n}{x}\)\(1\) 的贡献为 \(\log (n - \dfrac{n}{x}) + 1\)\(x > 1\)\(\log (n - \dfrac{n}{x}) + 1\)\(\log n\) 级别,显然 \(x + \log \dfrac{n}{x} > \log n + 1\),答案大致就是 \(x+ \log \dfrac{n}{x}\)

问题 2

输入这 $ n $ 个数,请你设计算法并写一个程序求解这个问题。

考虑二分答案,这样能对每个位置求出在树上的最大深度(对 \(n\) 取个 \(\min\))。从深到浅遍历每一层,每次如果这一层只剩一个点,那么直接升入上一层,否则先两两配对再升(为了满足条件,每层点数肯定越少越好)。最后如果第一层只剩一个点就合法,多个点不合法。时间复杂度 \(O(n \log V)\)

直接用合并果子的方式貌似可以 \(O(n \log n)\),但还是太有脑了。

代码咕咕咕。

问题 3

我们知道在二叉搜索树(有根有序二叉树)上,每个子树对应中序遍历的一个区间。
现在,你有 $ n $ 个点和 $ m $ 个区间约束 \([l_i, r_i]\),$ 1 \le l_i \le r_i \le n $。你要构造一个二叉搜索树,使得在树的中序遍历上,每个约束区间 \([l_i, r_i]\) 都恰好对应某一棵子树里的所有点。

问题 3.1

输入 $ m $ 个区间,输出是否存在这样的二叉搜索树。

首先要没有交,然后两个区间不能紧靠在一块(即存在 \(i,j\) 使得 \(r_i = l_j - 1\)),否则一定能构造,构造方式很简单。

问题 3.2

输入 $ m $ 个区间,构造一棵深度尽量小的满足条件的二叉搜索树。

只会 \(O(n^3)\) 的区间 DP。

问题 4

我们知道在一些数据结构问题中,经常出现这么一种“树套树”的情况:我们有很多个二叉搜索树,当我们查找到上层的二叉搜索树的叶子时,我们需要转到这个叶子关联的下层二叉搜索树,继续递归查找。或者反过来,从一个叶子不断向上跳,当跳到根时,根可能关联了一个上层二叉搜索树的叶子,我们需要转到那个叶子继续向上跳。

例如,在树链剖分中,如果我们给每个链开一个二叉查找树维护链上的所有点,查询一个点在原树上到根路径的过程就可以描述为不断在当前链对应的二叉搜索树上向上跳,到搜索树根之后再跳到当前链的链顶在原树上的父节点。这个点属于另一条链,然后我们继续在它的链搜索树上往上跳。循环往复直到跳到原树根节点所在的链的搜索树根。

现在给定一个有根树的树链剖分方式,所有 \(n\) 个树上的点被分成若干个祖先到子孙方向的链。请你找出一种二叉查找树形状的设置方法,使得在最坏情况下查询一个点在原树上到根路径的过程向上跳的步数尽可能少。你可以以此分析一下,假如树链剖分方式分别采用重链剖分和长链剖分,跳的步数复杂度是多少?

(在重链剖分时,这个算法在OI中被称为“全局平衡二叉树”)

首先跳链的复杂度不能变了。(重链剖分 \(O(\log n)\) 次,长链剖分 \(O(\sqrt n)\) 次)。

然后对每个点赋权其轻儿子的大小之和。每次找到带权重点进行划分。这样每次向上跳一次之后这个大小就会至少翻倍,大小到 \(O(n)\) 级别的时候,向上跳的次数为 \(O(\log n)\)

问题 5

现在我们看这样一个问题:
你和小明玩猜数游戏。有一张纸上画写了一些实数(设为数集 $ S $)。一开始,小明选一个在集合 $ S $ 里的数记在心里。然后每次你可以做两种询问:

  • 询问一个整数 $ x $,小明回答他的数和 $ x $ 的大小关系。
  • 询问一个实数 $ x $,小明回答他的数是否等于 $ x $。

请你设计一个足够优的策略使得最坏情况下询问次数尽可能少(渐进足够少即可),找出你表示这个询问次数需要从 $ S $ 中提取的关键信息/参数。并且给出最坏情况下询问次数的估计。

相当于将数分成一格一格(\([x,x+1)\) 一组),一格以内只能问实数,就变成问题 2 了。

问题 6

在问题5的基础上,你和小明从猜数升级到了猜点。

有一个平面上的点集 \(S\)(不妨设为用两维实数坐标表示)。

一开始,小明选一个在集合 \(S\) 里的点记在心里。然后每次你可以做两种询问:

询问一个网格直线 \(x\),小明回答他的数在直线 \(x\) 的哪一侧,或者恰好在直线上。(指水平或垂直且坐标为整数的直线)
询问一个任意直线 \(x\),小明回答他的点是否在这条直线上。
请你设计一个足够优的策略使得最坏情况下询问次数尽可能少(渐进足够少即可),找出你表示这个询问次数需要从 \(S\) 中提取的关键信息/参数。并且给出最坏情况下询问次数的估计。当然,这个问题可以对两维分别做一次问题 5,你能做到更优吗?

只会两次问题 5。但是一条直线能一次排除两个点,不知道怎么用。

本文作者:KIreteria

本文链接:https://www.cnblogs.com/11-twentythree/p/18699756

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   KIreteria  阅读(10)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起