2025.8.4 - 9.1

Question 1. 「2024 “钉耙编程” Round.1」I. 数位的关系

给定偏序关系限制串 \(R\),满足 \(R\) 中仅含 <> 且长度为 \(m\),称一数字串 \(S\) 满足 \(R\) 的限制,当且仅当:

  • \(S\) 的长度为 \(m+1\)
  • 对于任意的 \(i\in [1,m]\),若 \(R_i\)<\(S_i < S_{i+1}\),若 \(R_i\)>\(S_i > S_{i+1}\)

给定一数字串 \(T\),令 \(f(T,R)\) 表示 \(T\) 中满足 \(R\) 的限制的(不要求连续的)子序列的数量。

\(I(x)\) 表示将正整数 \(x\) 视作一个不含前导 \(0\) 的数字串,多次给定 \(l,r,R\),求:

\[\overset{r}{\underset{i=l}{\sum}} f(I(i),R) \]

\(T\leq 10, 1\leq l\leq r < 10^{500}, |R|\leq 500\)


感谢我同学 cyj 告诉我怎么写不那么史。

首先这个看起来很像数位 DP,套路性拆成 \([1,r] - [1,l] + \text{calc}(l)\),如果你是高精度大神,欢迎挑战写 \([1,r] - [1,l-1]\) 版本。

考虑如何搞定后面的 \(\text{calc}(l)\),不妨考虑直接 DP,令 \(m = |R|\) 则显然需要 \((m+1)\) 个数,设 \(f_{i,j,x}\) 表示考虑了前 \(i\) 位,拿了 \(j\) 个数丢进满足 \(R\) 的子序列,最后一次丢了 \(x\),为了方便,当 \(j = 0\) 的时候仅认为 \(x = 0\) 是合法的。

转移容易,考虑这一位用不用,如果用,设这一位为 \(x\),枚举上一个丢进去的数 \(y\),考虑 \((y,x)\) 是否满足当前要求的偏序关系,如果可以,则 \(f_{i,j,x}\gets f_{i-1,j-1,y}\)

不用的话,则 \(f_{i,j,x}\gets f_{i-1,j,x}\),初值为 \(f_{0,0,0} = 1\)

接下来考虑计算 \([1,r]\) 的答案,根据数位 DP 的套路很显然是会有一个位,在这个位没有卡满,同时导致之后的位在 \([0,9]\) 内任意,枚举这个位,则前面的一定是卡满的,可以沿用上述的 \(f\)

考虑这一位之后可以任意填 \(0\sim 9\),则设 \(g_{i,j,x}\) 表示从后往前考虑到了第 \(i\) 位,拿了 \(j\) 个数丢进满足 \(R\) 的子序列,最后一次丢了 \(x\),同理 \(j=0\) 时仅 \(x=0\) 合法,与 \(f\) 不同的是,\(g\) 需要在 \([0,9]\) 中枚举一个填在该位的 \(x\)

同时需要注意的是,\(g\) 的“该位不用”的状态的转移,必须在枚举完所有“用该位,且该位填 \(x\)”的转移之后,且转移为 \(g_{i,j,x}\gets 10\times g_{i+1,j,x}\),其中 \(10\) 表示这一位就 \([0,9]\) 任意了。

考虑此时如何计算答案,假设第 \(i\) 位是这个没卡满的位,那么可以通过 \(f_{i-1,j,x}\times g_{i+1,m+1-j,y}\times v\) 来计算答案,其中 \(v\) 是第 \(i\) 位如果不卡满该位的填数方案的数量,而 \((x,y)\) 依旧需要满足对应的偏序关系的限制,这种方法表示第 \(i\) 位不计入答案。

同时也可以通过 \(f_{i-1,j,x}\times g_{i,m+1-j,y}\),表示第 \(i\) 位计入答案,这个边转移“用该位”边算,具体来说转移 \(g_{i,/,y}\) 时算,偏序限制必须满足,这种方法表示第 \(i\) 位计入答案。

最终我们会面临一个问题:前导 \(0\) 在枚举状态时是存在的,但是在选子序列时不存在。但是又能发现只要填了前导 \(0\) 第一位就没有卡满,那么就容易解决:

多转移一次 \(g\),枚举有多少位是前导 \(0\),假设第 \(i(i\ge 2)\) 位是第一个非 \(0\) 位,考虑第 \(i\) 位用还是不用,用的话把 \(g_{i,m+1,x}\) 计入答案,同理边转移“用该位”边算,不用的话就枚举最高位最后一个丢进的数 \(y\in [0,9]\),把所有 \(g_{i+1,m+1,y}\) 计入答案即可。

不要忘记,不存在前导 \(0\) 时,第一位不能填 \(0\),这一点需要注意。设 \(n = |r|, k = |\Sigma| = 10\),时间复杂度为 \(\mathcal{O}(Tn^2k^2)\)

Question 2. Sum of distances

给定一张 \(n\) 个点的有向图,从 \(i\) 连向 \((i+1)\) 的边的边权为 \(a_i\),从 \(i\) 连向 \((i+2)\) 的边的边权为 \(b_i\),从 \(i\) 连向 \((i+3)\) 的边的边权为 \(c_i\),除此之外没有边。

求任意两点间的最短路之和。

\(n\leq 3\times 10^5, 1\leq a_i,b_i,c_i\leq 10^3\)


考虑分治,设中点为 \(m\),考虑拿出 \(m-1,m,m+1\) 这三个点,先分别求解完 \([l,mid-2], [mid+2,r]\),然后考虑 \([l,r]\) 区间的问题。

显然当 \(a\in [l,mid-2], b\in [mid+2,r]\) 时,显然一定要经过 \(m-1,m,m+1\) 中的一个。

\(d(x,y)\) 表示 \(\min(x,y)\to \max(x,y)\) 的最短路,先 DP 求解所有 \(d(a,m-1),d(a,m),d(a,m+1)\) 的最短路,注意方向不同 DP 不一定相同。

那么所有一端是 \(m-1,m,m+1\) 的答案容易求得,此处不要重复计数中间三个点之间的答案,考虑求 \(a\in [l,mid-2], b\in [mid+2,r]\) 时的答案。

假定最短路经过 \(x=m-1,y=m,z=m+1\) 中的一个点,且最短路相同时取编号更小者,则:

  1. \(x\) 中转:

    • \(d(a,x) + d(x,b)\leq d(a,y) + d(y,b), d(a,x) + d(x,b)\leq d(a,z) + d(z,b)\)
    • 转换!\(d(a,x) -d(a,y) \leq d(y,b) - d(x,b), d(a,x) - d(a,z)\leq d(z,b) - d(x,b)\)
    • 也即 \(P_a = (d(a,x) -d(a,y), d(a,x) - d(a,z)), R_b = [0, d(y,b) - d(x,b)]\times [0, d(z,b) - d(x,b)]\)
    • 数点 \(P_a\in R_b\),增加贡献 \(\sum d(a,x) + d(x,b)\)
  2. \(y\)​ 中转:

    • \(d(a,y) + d(y,b) < d(a,x) + d(x,b), d(a,y) + d(y,b)\leq d(a,z) + d(z,b)\)
    • 转换!\(d(a,y) -d(a,x) < d(x,b) - d(y,b), d(a,y) - d(a,z)\leq d(z,b) - d(y,b)\)
    • 也即 \(P_a = (d(a,y) -d(a,x), d(a,y) - d(a,z)), R_b = [0, d(x,b) - d(y,b))\times [0, d(z,b) - d(y,b)]\)
    • 数点 \(P_a\in R_b\),增加贡献 \(\sum d(a,y) + d(y,b)\)
  3. \(z\)​ 中转:

    • \(d(a,z) + d(z,b) < d(a,x) + d(x,b), d(a,z) + d(z,b) < d(a,y) + d(y,b)\)
    • 转换!\(d(a,z) - d(a,x) < d(x,b) - d(z,b), d(a,z) - d(a,y) < d(y,b) - d(z,b)\)
    • 也即 \(P_a = (d(a,z) -d(a,x), d(a,z) - d(a,y)), R_b = [0, d(x,b) - d(z,b))\times [0, d(y,b) - d(z,b))\)
    • 数点 \(P_a\in R_b\),增加贡献 \(\sum d(a,z) + d(z,b)\)

做几个二维数点即可,离散化后用树状数组跑得不慢。

而注意分治边界为 \(r-l+1\leq 2\),注意 \(r-l+1 = 2\) 时有一个点对。

时间复杂度为 \(\mathcal{O}(n\log_2^2n)\)

Question 3. [2nd-Ucup, Stage 12] K. Campus Partition

给定一棵 \(n\) 个节点的树,点有点权 \(a_i\),将树分成了若干连通块,每个连通块的权值为该连通块所有点权的非严格次大值,如果连通块大小为 \(1\) 则权值为 \(0\)

将树划分成若干连通块,划分方案的权值为所有连通块的权值之和,求所有划分方案的权值的最大值。

\(n\leq 5\times 10^5, a_i\leq 10^9\)


假设有一个大连通块,我们找到最大值所在点 \(u\),找到次大值所在点 \(v\),设路径 \(P\)\(u\to v\) 的路径,显然这个连通块的贡献不变,但是解放了更多点可以造成更多贡献,是更优的。

于是我们有结论:一个连通块仅需要一条路径,最大值与次大值分居路径两端。

考虑 DP,设 \(f_{u,w}\) 表示以 \(u\) 为根的子树,有一条需要向上的路径,路径另一端的权值为 \(w\) 的最大权值,设 \(g_u\) 表示以 \(u\) 为根的子树没有向上的路径时的最大权值。

则 DP 易求,设 \(v,w\) 为子节点:

\(u\) 开始新开一条路径:

\[f_{u,a_u} = \sum g_v \]

\(u\) 继承一条子树的路径:

\[f_{u,x} = f_{v,x} + \underset{w\ne v}{\sum} g_w \]

\(u\) 不选入路径(开单点):

\[g_u = \sum g_v \]

\(u\) 处合并两条路径:

\[g_u = f_{u,i} + f_{v,j} + \min(i,j) + \underset{w\ne v}{\sum} g_w \]

考虑能否按儿子节点顺序来执行 DP 的转移?可以,那么转移为:

\[\begin{aligned} f_{u,i } & \gets \max(f_{u,i} + g_v, f_{v,i} + S)\\ g_u & \gets \max(g_u + g_v, f_{u,i} + f_{v,j} + \min(i,j))\\ S & \gets S + g_v\\ \end{aligned} \]

记得考虑转移顺序,采用前后缀 \(\max\) 优化,分别考虑 \(\min(i,j)\)\(i\) 还是取 \(j\),设 \(pre_{u,j}\) 表示 \(x\leq j\)\(f_{u,x} + x\) 的最大值,同理 \(suf_{u,j}\) 表示 \(x\geq j\)\(f_{u,x}\) 的最大值,改写为:

\[g_u \gets \max(g_u + g_v, \max(f_{u,i} + i + suf_{v,i}, f_{u,i} + pre_{v,i})) \]

容易做到 \(\mathcal{O}(n^2)\)

发现两维状态均难以省去,考虑使用线段树合并进行优化,具体的,离散化 \(w\) 后开值域线段树,每个节点维护区间对应的 \(f_{u,i} + i,f_{u,i}\) 的最大值。

难点在于如何合并。设要将 \(q\) 节点合并到 \(p\) 节点上,如果均为叶子节点,则要么是 \(p\) 的值加 \(g_v\),要么是 \(q\) 的值加 \(S\),将 \(g_v,S\) 传入则可以取较大值。

\(p\) 为空,则显然取 \(q\) 的值加 \(S\);若 \(q\) 为空,则显然取 \(p\) 的值加 \(g_v\)。当然,这个加值需要下传,或者标记永久化,不这么做更新的时候会发现没有得到这个值。

合并的时候,先 pushdown。

考虑如何顺便更新 \(g_u\) 的值,传址进函数更新,每次递归的时候,同时计算当前区间 \([l,r]\) 对应的 \([1,l-1]\)\(f_{u,i} + i\) 的前缀最大值 \(P\)\([r+1,n]\)\(f_{u,i}\) 的后缀最大值 \(S\)

根据更新式,显然在 \(q\) 为空时,或者 \(l=r\) 时,\(g_u\) 需要更新,更新法则根据上述式子也容易得到。

时间复杂度为 \(\mathcal{O}(n\log_2 n)\),有一点细节。


旅游去了,东北好玩,天气挺凉快的。

顺便俄罗斯太平洋舰队的军舰和指挥部非常明显,还让拍照,挺有趣的。


Tips

  1. 逆序对指定的排列计数 DP 可以设 \(Q(i)\) 表示表示 \(P(i) > P(j)\)\(i < j\)\(j\) 的数量,然后基于两个条件求解:
    • \(Q(i)\leq N-i\)
    • \(\sum Q(i) = X\)
  2. 有时候不讲究复杂度的话,可以在换根时枚举转移到的节点的邻域,做一些小暴力,时间复杂度为 \(\mathcal{O}(N)\sim \mathcal{O}(N\log_2 N)\)

Question 4. 「2024 “钉耙编程” Round.1」K. 树上的 mex

给定一棵 \(n\) 个节点的树,点有点权 \(v_i(0\leq v_i\leq n)\),称树上的简单路径的权值为路径上所有点权的 mex。

求最大的非负整数 \(k\),使得树上至少有 \(1\) 条路径使得其权值为 \(k\),并求出权值为 \(k\) 的简单路径(端点 \(x,y\) 满足 \(1\leq x,y\leq n\))的数量。

特别的,对于任意点权 \(x\),都存在树上的一条简单路径,满足树上所有点权为 \(x\) 的点位于该路径上。

\(T\leq 10, n\leq 7\times 10^4, \sum n\leq 3.6\times 10^5\)


首先感觉这东西有单调性,二分 \(k\),对任意的 \(v\in [0,k)\),不经过点权 \(v\) 的路径不合法。

假设要求不经过点权 \(v\) 的路径,考虑建立点权 \(v\) 的所有点的虚树,由本题中点权的分布性质,显然这棵虚树是一条链。

那么考虑虚树中某个点权为 \(v\) 的点 \(u\),那么在 \(u\) 的某个儿子 \(x\) 的子树内的任意两点肯定不会经过点 \(u\),那么就不会经过点权 \(v\)。当然,如果子树内有一个点权为 \(v\) 的点 \(y\),要把这棵子树减去。如果用 dfs 序(用 \(d\) 表示 dfs 序,\(s\) 表示子树大小)区间来表示就是 \(a,b\in [d_x, d_x + s_x)\) 或者 \(a,b\in [d_x, d_y)\cup [d_y+s_y, d_x + s_x)\),其中 \(a,b\) 为路径端点。

考虑上述形式,可以用 \(xOy\) 平面上的矩形来表示,前面一种可以用 \(1\) 个矩形,而后面一种可以用 \(4\) 个矩形。

当然,假设这棵虚树的“上方”还有一批,分虚树的根 \(R\) 的权值是否为 \(v\) 讨论一下:

  • 如果根 \(R\) 的权值为 \(v\),则显然不在 \(R\) 的子树内的任意两点不经过点权 \(v\),则 \(a,b\in [1,d_R)\cup [d_R+s_R, n]\),可以用 \(4\) 个矩形描述。
  • 反之,\(R\) 必定存在两个儿子 \(s,t\),设 \(d_s < d_t\),则显然不在 \(s\)\(t\) 的子树内的任意两点不经过点权 \(v\),即 \(a, b\in [1,d_u)\cup [d_u+s_u, d_v)\cup [d_v+s_v, n]\),可以用 \(9\) 个矩形描述。

所有矩形的面积并表示所有不合法的路径数量,设面积并为 \(S\),则 \(n^2 - S\) 表示合法的路径数量,于是就容易 check 并计算答案。

估计一下矩形数量的上限:

  1. 对于“子树内”形式的矩形,在每个 \(x\) 处最多 \(4\) 个矩形,最多总计 \(4n\) 个。
  2. 对于“虚树外”形式的矩形,在每个 \(v\) 中最多 \(9\) 个矩形,最多总计 \(9n\) 个。

于是总矩形数量不超过 \(13n\),单次时间复杂度为 \(\mathcal{O}(n\log_2^2 n)\),有较大常数,实测上述做法可以通过。

Question 5. 「JOISC 2025 Day2」集邮比赛 4

本题又名:别样的集邮大战

给定一条长度为 \(2N\) 的环形跑道,跑道 \(i\) 连接站点 \(i\) 与站点 \(i+1\)(按照顺时针方向为 \(i\to i+1\)),特别的,跑道 \(2N\) 连接站点 \(2N\) 与站点 \(1\)(按照顺时针方向为 \(2N\to 1\)),跑道 \(i\) 上有一个集章台,提供颜色为 \(A_i\) 的印章。

参与者选择一个站点出发,支付 \(C_i\) 的代价,然后可以执行如下操作:

  • 选择一个不是起点的站点,交换与这个站点相连的两条跑道上的集章台,交换一次的代价为 \(X\)

最后,参与者从站点出发依次经过 \(2N\) 条跑道,假设先经过的某条跑道上的集章台的颜色为 \(X\),后经过的为 \(Y\)(可以是同一条),可以获得一张「左边为颜色 \(X\) 右边为颜色 \(Y\)」的卡。

称两张卡不同当且仅当其有至少一边的颜色不同,给定 \(Q\) 个询问,每个询问求得到至少 \(K_q\) 种卡的代价。

\(N,X,Q\leq 5\times 10^5, C_i\leq 10^{18}, K_q\leq N^2\),且 \(A\)\((1,1,2,2,\cdots, N,N)\) 的一个排列。


我们不妨考虑指定一个起点,在不交换的情况下,依次经过 \(2N\) 条跑道,依次经过的 \(2N\) 个集章台的印章的颜色构成的序列为 \(B=(B_1,B_2,\cdots, B_{2N})\)

如果执行一次交换操作,则相当于选择 \(1\leq i < 2N\) 然后交换 \(B_i, B_{i+1}\)

考虑到每种元素恰好出现两次,我们不妨设一个长度为 \(2N\) 括号序列 \(S\),其中某个数值 \(X(1\leq i\leq N)\) 第一次出现的位置 \(i\) 对应的 \(S_i\)(,第二次出现的位置 \(j\) 对应的 \(S_j\)),那么肯定有 \(S\) 是合法括号序列。

接下来刻画能够得到的卡的数量,就是前面是 ( 后面是 ) 的二元组数,严谨的说:满足 \(i < j\)\(S_i\)(\(S_j\))\((i,j)\) 的数量。

同时,对于两边颜色相同的卡,两个章也强制在不同的集章台盖章,这将稍微简化问题的考察。

考虑这个字符串 \(S\),除非前 \(N\) 个都是 ( 且后 \(N\) 个都是 ),都一定能找到一对 )( 且这两个括号是相邻的,执行一次交换后变为 (),并且这个括号序列最终总能变为「前 \(N\) 个都是 ( 且后 \(N\) 个都是 )」的形式,每一次交换会增加一个且仅增加一个 () 的二元组(毕竟交换的是相邻的)。

所以,设 \(P_i\) 表示从站点 \(i\) 开始得到的这个序列 \(B\) 对应的 \(S\),不交换的初始情况下,对应的二元组的数量,先暴力求得,时间复杂度为 \(\mathcal{O}(N^2)\)

接下来对每一个询问给出的 \(K_q\),从站点 \(i\) 开始所需要的最小代价为 \(C_i + X\cdot \max(K_q - P_i, 0)\),与 \(0\)\(\max\) 表示 \(P_i\geq K_q\) 时无需操作,这个也暴力,时间复杂度为 \(\mathcal{O}(QN)\)

现在总时间复杂度为 \(\mathcal{O}(N(N+Q))\),考虑对两个暴力进行优化。

已知 \(P_i\) 时对计算答案进行优化

这个部分主要需要考虑 \(\max(K_q - P_i , 0)\),尝试将 \(P_i\) 从小到大考虑。

此时 \(P_i\) 变得升序了,那么每一个 \(K_q\)\(P_i\) 较小的时候取得 \(K_q - P_i\) 项,代价为 \(C_i + X(K_q - P_i)\),即 \(X\cdot K_q + (C_i - X\cdot P_i)\),前者固定 \(K_q\) 后是常数,后者仅跟 \(i\) 有关,可以采用前缀最小值计算。

而在 \(P_i\) 较大的时候取得 \(0\) 项,代价为 \(C_i\),可以用后缀最小值计算。

\(K_q\) 二分其在 \(P_i\) 升序后中的位置,容易在线计算答案,本部分时间复杂度变为 \(\mathcal{O}(Q\log_2 N)\)

\(P_i\) 的计算进行优化

计算 \(P_i\) 的时候需要从位置 \(i\) 断环求解序列问题,不妨先将原 \(A_i\) 断环成链,倍长(复制一段接到末尾),然后求解所有长度为 \(M = 2N\) 的区间的答案。

求解一段序列中「前面是 ( 后面是 )」的二元组数,可以用线段树进行维护,具体的,维护每个节点中 ( 的数量、) 的数量与对应的二元组数量,合并的时候除了两个子区间的二元组数量,还要加上左半部取 ( 且右半部取 ) 的方案数,并且这个容易做简单的修改操作。

不妨随便指定一个顺序(从前往后或从后往前)计算,因为笔者此处的 \(P_i\) 定义的为开头位置,所以此处选择从后往前。

开一棵定义在 \([1,2M]\) 区间上的线段树,先预处理后半段 \([M+1,2M]\) 的答案,考虑每次往前加入一个位置 \(s\) 带来的影响。

加入 \(s\) 的同时,要将 \(s+M\) 位置的影响删除,但是序列是倍长得到的,所以显然有 \(A_s = A_{s+M}\),也就是说,我们需要将 \(s\) 位置改成一个 (,同时一定存在另一个位置 \(t\in [s, s+M)\) 满足 \(A_s = A_t\),原因还是一样,要做的是将 \(t\) 位置改成一个 )。而在此之前,\(t\) 位置是 (\(s+M\) 位置为 )

所以从前面加入一个位置带来的影响就是 \(3\) 次单点修改(其实 \(2\) 次就能做了,但是为了贯彻“删除影响”的描述记为 \(3\) 次),这个是容易做的。

于是边加入位置边用线段树维护计算出 \(P_i\) 即可,时间复杂度为 \(\mathcal{O}(N\log_2 N)\),实际上考虑的序列的长度已经是 \(4N\) 了,但是实测不会超时,跑起来不算慢。

综合两大优化,本题得以在 \(\mathcal{O}((N+Q)\log_2 N)\) 的复杂度内求解,可以通过。

Question 6. 「CQOI2011」动态逆序对

设一长度为 \(n\) 的排列 \(P\),给定 \(m\) 次操作,每次操作从 \(P\) 中删除一个指定的数,求每次操作 \(P\) 中的逆序对数量。

\(m\leq n\leq 10^5\)


先强制钦定出一个排列 \(Q\),将 \(P\) 中元素按照 \(Q\) 的顺序删除,之后不妨将逆序对 \((i,j)\) 挂到删除早的元素上,那么无非两种形式:

\[\begin{aligned} i &< j\\ a_i &> a_j\\ t_{a_i} &< t_{a_j}\\ \end{aligned} \]

\[\begin{aligned} i &< j\\ a_i &> a_j\\ t_{a_i} &> t_{a_j}\\ \end{aligned} \]

将下标为第一维,元素值为第二维,删除时间为第三维解三维偏序,CDQ 分治即可,不要忘记答案是差分过的,后缀和回去即可,时间复杂度为 \(\mathcal{O}(n\log_2 ^2 n)\)

Tips

  1. STL 定义申请空间很慢,所以不要在动态 DP 的矩阵乘法里面的矩阵用 vector 之类的STL!本机实验相差 10 倍,可以使用 array 之类。
  2. 尝试找出 DP 中两个运算的分配律关系,构建矩阵乘法维护动态 DP。

Question 7. 「JOISC 2025 Day3」多方通信

\(N\) 个人,每个人手上有一块白板,初始裁判决定一个人是贵族,其他人是平民,初始时贵族手上的白板上写有 T,所有平民的白板上写有 F

通过执行以下操作 \(L\) 轮,找出贵族:

  • 每个人先擦去白板上写有的字符,基于先前轮依次所看过的所有字符(包括初始字符),然后自行选定一个 TF 的字符写入白板。
  • 基于先前轮依次所看过的所有字符(包括初始字符),每个人 \(x\) 指定一个人 \(y\) 并查看 \(y\) 的白板上的字符,此时可以 \(x = y\)

\(L\) 轮操作后,通过所依次查看过的人及其写下的字符,报出贵族的编号。

最小化 \(L\),并依次给出每个人是贵族时的情况时每个人会做什么。

解决 \(N = 4, 32, 48\) 时的问题。

测试点编号 \(N=\) 计分方式 满分
\(1\) \(4\) \(\displaystyle \textsf{得分}=\begin{cases} 0 & 4\lt L \\ 16-7\cdot (L-2) & 2\lt L\le 4 \\ 16 & L\le 2\end{cases}\) \(16\)
\(2\) \(32\) \(\displaystyle \textsf{得分}=\begin{cases} 0 & 27\lt L \\ 60-3(L-8) & 8 < L \leq 27 \\ 60 & L\le 8\end{cases}\) \(60\)
\(3\) \(48\) \(\displaystyle \textsf{得分}=\begin{cases} 0 & 9\lt L \\ 24 & L\le 9 \end{cases}\) \(24\)

首先考虑一个最简单的策略,每一轮都是贵族写 T 平民写 F,然后每个人遍历其他 \(N - 1\) 个人,直到找到一个写 T 的为止,需要 \(L = N-1\) 轮,可以获得 \(9\) 分。

稍微优化以下,遍历 \(N - 2\) 个人,如果都没有找到 T,基于自己的字符,推断剩下的一个人是否为贵族,需要 \(L = N-2\) 轮,可以获得 \(16\) 分,解决 \(N = 4\) 的问题。

于是策略就出来了,我们不断排除一些玩家,直到能够确定贵族是谁,一个比较容易想到的方法是分组,考虑 \(N = 32\),例如:

  • \(32\) 个人分成 \(8\) 组,每组 \(4\) 个人,先在组内 \(3\) 轮找出是否在本组内有,接下来 \(6\) 轮遍历 \(6\) 个其余组是否有贵族(此时有贵族的组全员写 T 其余组全员写 F),最后再在组内问 \(3\) 个人,即可推断出贵族是谁,总花费 \(12\) 次,可以获得 \(16 + 48 = 64\) 分。

列一个不等式就可以发现分组是不可能达到 \(L = 8\) 的目标的,考虑再优化。

不妨将 \(32\) 个人放到线段树上,如果已知是在 \([1,16]\) 中还是在 \([17,32]\) 中,就可以通过递归子树来确定,通过在长度为 \(2\) 的区间处进行一次推理,可以在 \(4\) 次之内找出(长度为 \(16,8,4,2\) 的区间各一次)。

至于确认贵族编号的第一次确定,已知其中有一个叶子节点是贵族,所以按照深度从大到小询问,深度相同的在一次询问内进行,每一次询问合并其左右子树是否存在(即 \(f_s = f_l \operatorname{OR} f_r\)),询问方法为:

  • 由左右子树所对应区间长度相同,左子树与右子树节点一一对应,问自己节点对应的节点,写自己是否已知贵族存在即可。

最终就可以 \(4\) 次恰好分出 \([1,16]\) 还是 \([17,32]\),叠加上上面的 \(4\) 次询问,得以在 \(8\) 次解决问题。

至于 \(N = 48\) 时的情况,相当于在合并到 \([1,16], [17,32], [33,48]\) 时通过额外一次确定在哪一组,因为已知自己所在组,随便询问另外一组,均不存在可以通过排除法确定贵族所在组,\(L = 9\) 解决。

posted @ 2025-08-04 10:35  ydzr00000  阅读(29)  评论(0)    收藏  举报