2026.10 模拟赛总结
10.3 模拟赛总结
代码源 CSP-S 模拟赛 Day 14。为什么缺少 day 13 呢?因为当天是 10.1,当然要庆祝祖国母亲生日了。
8:01 开赛(来晚了)。T1 给定一棵树和一个排列,初始全体点属于一个小组,对每个小组选择其在排列中最靠前的点 \(u\) 作为小组长,然后在 \(u\) 所处连通块中删除点 \(u\) 及连边,剩余的连通块作为下级小组,继续如上选择下级小组长,并令下级小组长的直接上级为 \(u\)。求每个点的直接上级。
考虑 \(x\) 的直属上级是 \(y\),充要条件应该是 \(y\) 在 \(x\) 之前,且 \(x, y\) 的路径上没有在 \(x\) 之前的点,那个排列最后的 \(y\)。
倒序考虑 \(x = p_i\)。初始都是标记点,先把 \(x\) 改为未标记点,于是未标记点构成若干个连通块,维护每个连通块的相邻点(其必然为标记点,在 \(x\) 之前),\(x\) 的直属上级就是 \(x\) 所处连通块相邻点中排列最靠后的点。
可以 set 维护相邻点的下标,按秩合并(按 set 大小),感觉是 \(O(n\log n)\)?
8:59 提交 T1,期望得分 \(100\) 分。(我在 10.16 回头去看这个题感觉当时的我怎么这么强,这么快就会了)。
然后磕了会 T2,发现没有任何思路,也不会暴力。迅速修改策略,跳过 T2,先拼 T3, T4 暴力。T3 题意,\(n\) 数组,\(q\) 次询问 \(l, r, k\),可以交换相邻两个总和不超过 \(k\) 的数,问是否能令区间单调不降。性质:询问 \(k_i < \min w_j\),显然不能进行任何操作,直接判断询问区间是否单调不降即可。然后 \(O(nm)\) 也是好做的,重要元素是前缀最大值,因此遍历询问区间,维护前缀最大值 \(maxn\),若 \(maxn > w_i\) 则需将 \(w_i\) 交换至 \(maxn\) 之前,因此至少需要交换 \(maxn, w_i\),若其合法,则 \(w_i\) 和任意元素交换都合法,前缀必然合法。
10:12 提交 T3,期望得分 \(30\) 分。然后 T4,还是树,找一条极长路径,求路径长度乘以,所有点到路径的距离的最大值,该乘积的最大值,以及达到该乘积的路径数量。显然可以枚举路径起点(叶子节点),以其为根 DFS,容易得到每个点到子树内叶子结点的最大距离 \(maxd_u\)。然后 DFS 求答案,用可重集 \(h\) 维护可能的答案。到达新点 \(u\) 时,先把所有儿子 \(v\) 的 \(maxd_v + 1\) 存入 \(h\),然后枚举儿子 \(v\),删除 \(maxd_v + 1\),继续递归,最后加回来。到叶子节点时更新答案即可。这是 \(O(n^2\log n)\) 的,竟然被卡了,暂时不会优化。
10:53 提交 T4,期望得分 \(19\) 分。只能回来看 T2 了。又磕了一个小时,只能写了个概率 \(p = 50\) 的特殊性质。
11:59 卡点提交 T2,期望得分 \(10\) 分。同时出成绩:\(100 + 10 + 30 + 19 = 159\)。
仍然没有看懂 T2 题解。T3 是支配对,转化一下:求 \([l, r]\) 中,和最大的逆序对之和,是否 \(\le k\)。设 \(p[j]\) 表示满足 \(w[p[j]] > w[j], p[j] < j\) 的最大 \(p[j]\)。只需要考虑全体点对 \((p[j], j)\),因为设和最大(和相同时 \(i\) 最大)的逆序对为 \((i, j)\),必有 \(i \le p[j]\),当 i$ < p[j]$ 时:若 \(w[i] \le w[p[j]]\),\((p[j], j)\) 更优,矛盾;否则,\((i, p[j])\) 更优,矛盾。因此,\(i = p[j]\)。将询问按 \(r\) 离线排序,线段树在 \(p[j]\) 处对 \(w[p[j]] + w[j]\) 单点取 \(\max\),对 \([l, r]\) 区间求 \(\max\)。
T4 也是好题,枚举分叉点(有至少三条连边),以其为根,向三个不同子节点引出最大的三条不相交的极长链,设其长为 \(a \ge b \ge c\)。最优必然是 \(b, c\) 构成主路线,\(a\) 作为最大距离,答案为 \(a(b + c)\)。难点在于计数。若 \(b > c\),求引出长为 \(b, c\) 的极长链的数量,相乘即可。否则 \(b = c\),求引出该长的极长链在每个子结点子树内的数量分别为 \(m_1, m_2, \dots\),两两相乘之和,就是(和平方 - 平方和 / 2)$。这样会不会将主路线数计重呢?不会。对于同一条主路线,最优分叉点只有一个。否则,其不可能是答案。点 \(u\) 维护向所有子节点引出的极长链的长度及数量,换根 dp 即可。
10.4 模拟赛总结
jsy 模拟赛。仍然是四道题,比赛介绍:《比赛不难》。
8:00 开赛,有两个模数 \(p < q\),每次选择长度至少为 \(k\) 的区间,选择一个模数,区间整体对其取模。求总和最小值。显然取模必然不劣于不取模,因此每个数要么是对 \(p\) 取模,要么是依次对 \(q, p\) 取模。取模过的数再取模不会有任何影响,这一点很重要。如果没有长度限制,必然是每个数选择最优情况。有了限制后,希望选择最优情况的尽可能多。发现可以初始对一段长为 \(k\) 的区间 \([l, r]\) 取模,剩下的数就可以选择最优情况了(例如 \(l - 1\) 最优情况为 \(p\),选择区间 \([l - 1, r]\) 对 \(p\) 取模即可)。并且不可能有更多的最优情况。枚举区间即可。
10:01 提交 T1,期望得分 \(100\) 分。看了眼 T2, T3 都没有思路。T4 是大数据结构,打暴力最爽了,就你了。原题是区间加、区间改为 \(\operatorname{popcount}\)、单点查询,显然我不会。但是 \(O(nq)\)、没有区间改为 \(\operatorname{popcount}\)、单点 \(\operatorname{popcount}\)、区间加位于区间改为 \(\operatorname{popcount}\) 之前、区间 \(\operatorname{popcount}\) 不超过 \(20\) 个、区间 \(\operatorname{popcount}\) 区间长度总和不超过 \(2 \times 10^6\),显然都是好做的,暴力和线段树呗。
11:24 提交 T4,期望得分 \(80\) 分。T3 暴力也是好做的,\(m > n, m = n, m = 1\) 时分别输出 \(0, 2^n, \sum\limits_{i = 1}^n abs(i - (n - i))\)。剩下的临时想了个 DP,设 \(dp[i][sa][sb]\) 表示有 \(i\) 个箱子,共装 \(sa\) 个红球,\(sb\) 个蓝球,所有方案的权值之和,竟然一遍过样例了,得到了一个猎奇的 \(O(mn^4)\) 做法。
11:46 提交 T3,期望得分 \(40\) 分。最后回到 T2,对字符串 a 进行 \(n\) 次操作 \(c, t\),每次将原串中的字符 \(c\) 替换为字符串 \(t\),最后求 \([l, r]\) 是什么。显然没时间想正解了。写了点 \(|T| = 1\) 和最终串长 \(\le 2 \times 10^5\) 的暴力,竟然还是一遍过样例。
11:58 提交 T2,期望得分 \(20\) 分。这么说我能拿 \(240\)?
12:00 出成绩:\(100 + 28 + 44 + 40\) 分。T4 挂了 \(40\) 分!原本写的是用 \(tag\) 标记区间被 \(\operatorname{popcount}\) 了几次,不知道为啥错了。由于是暴力,不用到 \(tl \le l \le r \le tr\) 时结束,而是在 \(l = r\) 时结束,也就是对每个叶子节点 \(\operatorname{popcount}\)。复杂度仍然是对的,能拿到 \(80\) 分。正解我不会。
mxf 怎么做到赛时通过 T2 的???构建树状物,倒着枚举操作,每次操作新建虚点代表本次操作,其代表字符为 \(c\),连向 \(t\) 中字符 \(t_i\) 最后一次操作的节点。这样树可能很长,优化就是对于链(例如 \(a\rightarrow b \rightarrow c\)),用并查集维护最下面的节点,这样就可以避免很多次跳跃。这题不适合理性理解,适合感性理解(放松大脑皮层)。
T3 转化题意:\(|a - b|\) 就是将红蓝小球匹配,剩下的球数。枚举 \(p\) 为匹配对数,表示有 \(p\) 对红蓝小球,分配到 \(m\) 个盒子,可以为空,方案数为 \(C(p + m - 1, m - 1)\)。剩余 \(n - 2 * p\) 个小球,分配到 \(m\) 个盒子,不可以为空,每个盒子内的小球颜色统一,可以是红或蓝,分配颜色方案数为 \(2^m\)。钦定完颜色,只考虑数量,求所有方案的盒子内球数之积的和,即每个盒子选一个球的方案数之和。插板法,在小球中插 \((m - 1) + m\) 个板,偶数位置 \(m - 1\) 个板划分盒子,奇数位置 \(m\) 个板代表每个盒子选的球,方案数为 \(C(n - 2 * p + m - 1, (m - 1) + m)\)。三者相乘求和即为答案。
10.5 模拟赛总结
qy 模拟赛,赛后得知都是 USACO 的好题。
8:00 开赛。T1 一眼签到,但是我脑子卡了会哈哈哈。\(N \times N\) 的网格,初始只有 \((1, 1)\) 是亮的,其他都是暗的,\((a, b)\) 控制 \((c, d)\) 的灯。求从 \((1, 1)\) 出发,亮的最多数量。维护两个 bool 数组表示是否可达(仅代表可以合法移动到这里),是否亮。
8:48 提交 T1,期望得分 \(100\) 分。然后已经通读 T2, T3,没有思路,写 T4 暴力。有 \(t\) 个括号串,求它们在某个区间都是合法括号串的区间数量。暴力是好做的。
9:31 提交 T4,期望得分 \(40\) 分。T3 我是真没招了,写的 \(O(nk\log n)\) 它就是只能过 \(n, k \le 100\),为啥 \(n, k \le 1000\) 跑这么慢啊???此外猜测数据很水,于是写了一点特判,就是把最优解方案(每个位置选择任意一个最小值)都算上,再把最优解每个位置选择次小值得到的方案排序,看能不能得到前 \(k\) 小的方案。
10:24 提交 T3,期望得分 \(10\) 分。T2 也是神人题,写了个一眼假的贪心,而且很麻烦,根本不知道期望得分多少分。
12:00 出成绩:\(100 + 15 + 40 + 40\) 分。T2 贪到了一点分,感觉是西西弗数据强度。T3 甚至特判多了 \(30\) 分。T4 甚至最后一个包只 T 了一个点,还是个全部 \(()\) 交替的。我当时赛时想到这个了,但是觉得反正也是暴力,特判就不写了吧,结果写了就能过(水数据)??
T2 由于泥土数量很少,对每块泥土考虑。如果要添加,要么就是直接获得,代价 \(x\),要么钦定它从之前某个有多的泥土搬过来,设之前那块泥土代价为 \(val\),则本次代价 \(z * (i - j) - val = z * i - (z * j + val)\),因此对每个有多的泥土存大根堆,存 (z * i + val)$。要删除同理。
T3 先把每行的每个数排序,暴力的话肯定是记录状态表示每行选择第几个数,每次选择一行,令其选择的数往后推。优化的话,发现每个状态会被不止一个前驱状态入堆,因此钦定每个状态的前驱状态,就是这个状态的最后一行选择前一个数的状态,如果最后一行已经选了最小的就从下往上选择第一个可以更小的行。但是,一个状态仍然有很多后继,发现这些后继有共同点:设该状态从下往上第一个可以更小的行为第 \(i\) 行,则后继状态是第 \(i\) 行或第 \(i + 1 \sim n\) 行中选择一行往后推得到的状态,这里暂时不考虑第 \(i\) 行。这些后继状态是没有必要同时入队的,因为前驱后继的要求是前驱花费小于后继花费,因此可以让这些后继状态中,最小的那个入队,令它的后继是第二小的那个,以此类推。发现花费最小的后继状态,就是对应的那一行的 \(c_2 - c_1\) 最小的状态。因此,初始将所有行按 \(c_2 - c_1\) 排序,则状态的那么多后继中,只需令第 \(i + 1\) 行往后推的后继入队即可。同时,我们希望第 \(i + 2\) 行往后推的后继,作为 \(i + 1\) 行往后推的后继。
因此,思路大概总结出来了:初始把每行的每个数排序,将所有行按 \(c_2 - c_1\) 排序。设状态 \((x, y, cost)\) 表示前 \(x - 1\) 行已经固定,第 \(x\) 行选择第 \(y\) 个数,第 \(x + 1 \sim n\) 行选择第 \(1\) 个数,花费 \(cost\)。后继状态有至多三个:第 \(x\) 行往后推,第 \(x\) 行固定、第 \(x + 1\) 行往后推,(当 \(y = 2\) 时)第 \(x\) 行固定选择 \(1\)、第 \(x + 1\) 行往后推。新花费也是好求的。
好题,好题。
T4 听他们说是简单题,我根本没看出来。区间合法,需要满足 \(sum[i][r] = sum[i][l - 1] \land sum[i][l - 1] \le sum[i][j](j \in [l, r])\)。对于第 \(i\) 个串,设 \(h[j]\) 为第 \(j\) 列的 \(sum[i][j]\) 的哈希值,\(R[j]\) 为 \(j\) 后面最小的 \(p\) 使得 \(h[p] = h[j - 1]\),则 \([l, R[l]]\) 满足条件一,若其满足条件二,则有 \(dp[l] = dp[R[l] + 1] + 1\),其中 \(dp[l]\) 表示以 \(l\) 为左端点的合法区间数,意思是对于左端点为 \(R[l] + 1\) 的区间,其左端点改为 \(l\) 得到新的区间,同时另加一个 \([l, R[l]]\),它们都是合法的。考虑条件二,设 \(nxt[j]\) 表示:当所有 \(s[i][j] = '('\) 时,\(j\) 后面最小的 \(p\) 使得 \(sum[i][p] < sum[i][j]\),对于所有 \(i\) 的 \(p\) 取最小值。当存在 \(s[i][j] = ')'\) 时,\(nxt[j] = j\)。从后往前考虑,记录 \(sum[i][j - 1] - 1\) 最后一次出现的位置(包括自己),它就是对于 \(i\) 的 \(p\)。那么,\(R[l]\) 满足条件二就是要满足 \(R[l] < nxt[l]\)。
10.6 模拟赛总结
代码源 CSP-S 模拟赛 Day 15。这是悲伤的一天。
8:00 开赛。all in T1 没 in 出来,T2, T3 暴力不好写,于是去写 T4 暴力,然后本来可以直接 DFS 做的,但我非要弄个树剖维护链上最大边权。结局是好的,期望得分 \(25\) 分。T1 也是暴力,感觉都没啥可说的,性质题不想性质就白搭。
12:00 出成绩:\(60 + 0 + 0 + 25 = 85\) 分。T1 又被随机区分了,第一步性质就没想出来。有两堆硬币,个数分别为 \(1, n\),设当前两堆个数分别为 \(A, B\),每次从第二堆硬币中取不超过当前 \(\gcd(A, B)\) 个硬币,移至第一堆。求将第二堆硬币取完的最小次数。由于硬币总数不变,可得 \(\gcd(A, B) = \gcd(A, n + 1)\)。对 \(n + 1\) 因数分解,设因数为 \(1 = d_1 < d_2 < \dots < d_D = n\),设 \(f_i\) 表示 \(A = d_i\) 时的最小次数,从 \(f_j\) 转移到 \(f_i\) 的最优策略是从 \(A = d_j\) 开始,每次加 \(d_j\),一直有 \(d_j \le \gcd(A, n + 1)\),直到最后让 \(A\) 加上一个 \(\le d_j\) 的数达到 \(d_i\),操作次数为 \(\left\lceil\frac{d_i - d_j}{d_i}\right\rceil\)。这样必然合法,为什么最优呢?发现对于选择的最优 \(j\),其实 \(\gcd(A, n + 1)\) 一直是等于 \(d_j\) 的,因为如果等于 \(k \cdot d_i(k > 1)\),那 \(k \cdot d_i\) 也是 \(n\) 的因数,此时从 \(k \cdot d_i\) 转移过来更优秀(操作次数更少),这与 \(j\) 最优矛盾。
后面的题根本订不动。
10.8 模拟赛总结
代码源 CSP-S 模拟赛 Day 16。这也是悲伤的一天。
7:56 开赛。all in T1 没 in 出来,没看 T2, T3, T4。可是 cyz \(5min\) 秒了 T1,我只写了 \(60\) 分的 \(O(n^2)\)暴力,题面的“操作区间必须包含或不相交之前的操作区间”限制不好做,考虑倒着操作,就是“操作区间必须被之前的操作区间包含或与其不相交”,每次扫一遍,找到所有 \(a[i] \ne i\) 的区间 \([min(a[i], i), max(a[i], i)]\),然后对其扫一遍,如果和之前维护的区间相交了,就合并;否则,就对维护的区间反转,维护区间变成自己这个区间。如果有重复操作的区间,就是 \(-1\)。
正解是(cyz 做法),维护递增块和递减块,初始每个数自己一个块,每个块维护递增/递减、最大最小值。如果有相邻的块满足:左块最小值等于右块最大值加一,则可合并成递减块,算一下答案;左块最大值加一等于右块最小值,则可合并成递增块,算一下答案。可以直接从左到右扫一遍,用栈维护之前的块,加入 \(i\) 这个单独的块后不断取栈顶和栈第二个,判断合并。最后剩一个块就是合法的,否则不合法。
T2 也是神人题。考虑一段长为奇数的区间 \([l, r]\),除一个点外,剩下的点都已两两配对,钦定剩下那个点连向区间外且它连出去的边是该区间的根。
性质是:\([l, r](l < r)\) 必然可以分成三段长为奇数的区间 \([l, p], (p, q], (q, r]\),使得左右两个区间剩下的点互连,中间区间剩下的点作为大区间剩下的点(向外连边必然会经过 \([l, p], (q, r]\) 剩下的点之间的边,因此其可为根)。
发现并不需要维护剩下的点是谁,只要满足 \(s_{(p, q]} = s_{[l, r]} \land |s_{[l, r]}| = 1\),其中 \(s\) 表示区间和,红为 \(+1\),蓝为 \(-1\),那么 \(s_{[l, p]} + s_{(q, r]} = 0\),从而左右区间剩下的点必然异色。这是充要的吧。
因此,设 \(f_{l, r}\) 表示区间 \([l, r]\) 的方案数,当 \(|s_{[l, r]}| \ne 1\) 时,值为 \(0\);否则,\(f_{l, r} = \sum\limits_{s_{(p, q]} = s_{[l, r]}} f_{l, p} \times f_{p + 1, q} \times f_{q + 1, r}\),要求三段长为奇数且非空。不用担心 \(|s_{[l, p]}|, |s_{(q, r]}|\) 是否有可能不是 \(1\),如果不是 \(1\) 的话 \(f\) 就是 \(0\) 了,不会算入答案,因此必然是 \(1\),也就是能够恰好配对完后剩下一个点。
暴力是 \(O(N^4)\) 的,其中 \(N = 2n\) 因为点数是 \(2n\)。简单的 trick 是,设 \(g_{l, q, t = -1/1} = \sum\limits_{s_{(p, q]} = t} f_{l, p} \times f_{p + 1, q}\),则有 \(f_{l, r} = \sum\limits_{q} g_{l, q, s_{[l, r]}} \times f_{q + 1, r}\)。
枚举区间长度,偶数更新 \(g\),奇数更新 \(f\)。注意初始有 \(f_{l, l} = 1\)。时间复杂度 \(O(N^3)\),可以卡过。
T4 好题,对于排列,一直选择相邻逆序对,删除其中一个数,直到无法操作,求最终序列数量。
将删数视为合并块,每块仅留一个位置 \(k\) 作为代表,即 \([l, r]\) 仅留 \(k\)。充要条件为 \(a[l] \ge a[k] \ge a[r]\)。证明:
必要性(结论 \(\rightarrow\) 条件):归纳法,\(l = r\) 时,条件正确;合并块,设左留 \(x\),右留 \(y\),需 \(a[x] > a[y]\),最后留 \(z = x/y\),易证 \(a[l] \ge a[z] \ge a[r]\)。
充分性(条件 \(\rightarrow\) 结论):引理:若 \(a[l] > a[r]\),则可仅留 \(l/r\)(证明:当 \(len > 2\) 时,必然存在相邻逆序对且至少一个位置不为 \(l/r\),删除该位置直至 \(len = 2\))。若 \(l < k\),则 \(a[l] > a[k]\),\([l, k]\) 可仅留 \(k\);否则,\(l = k\),\([l, k]\) 亦可仅留 \(k\)。\([k, r]\) 同理可仅留 \(k\)。
设最终有相邻保留位置 \(i < j(a[i] < a[j])\),需存在 \(t \in [i, j)\),使得 \([i, t]\) 可仅留 \(i\),\((t, j]\) 可仅留 \(j\),即 \(a[t] \le a[i], a[t + 1] \ge a[j]\)。
特别地,对于第一个保留位置 \(i\),有 \(a[i] \le a[1]\);对于最后一个保留位置 \(j\),有 \(a[j] \ge a[n]\)。
设 \(dp[j]\) 表示考虑 \(1 \sim j\),钦定保留 \(j\) 的方案数。若 \(j\) 为第一个保留位置,则 \(dp[j] = [a[1] \ge a[j]]\);否则,令 \(i\) 为上一个保留位置。记 \(m = \max\limits_{t \in [i, j) \land a[t] \le a[i]} a[t + 1]\),则 \(dp[j] = \sum\limits_{i < j \land a[i] < a[j] \le m} dp[i]\)。
\(O(n^2)\) 是好做的,枚举 \(i\),向后枚举 \(j\) 更新 \(m\) 和 \(dp[j]\)。发现可以 CDQ 分治:先递归左,再由左推右,最后递归右。令 \(mid = \left\lfloor\frac{l + r}{2}\right\rfloor\)。
考虑 \(t \in [l, r)\),拆分为 \(t \in [l, mid)\) 和 \(t \in [mid, r)\)。
设 \(L[i] = \max\limits_{t \in [i, mid) \land a[t] \le a[i]} a[t + 1], R[j] = \min\limits_{t \in [mid, j) \land a[t + 1] \ge a[j]} a[t]\)。从 \(mid\) 向前推 \(L[i]\),从 \(mid + 1\) 向后推 \(R[j]\),分别需要值域树状数组维护前缀最大值/后缀最小值。
由左推右的充要条件为:\(a[i] < a[j] \land (L[i] \ge a[j] \lor R[j] \le a[i])\)。
直接加可能计重,需要容斥:\(a[i] < a[j]\) 的 \(dp[i]\) 之和,减去 \(L[i] < a[j] \land a[i] < \min(a[j], R[j])\) 的 \(dp[i]\) 之和。
两者都需要值域树状数组维护前缀和。前者对左扫一遍,对 \(a[i]\) 处加 \(dp[i]\),询问 \(a[j] - 1\) 前缀和。
后者令左按 \(L[i]\) 排序,右按 \(a[j]\) 排序,双指针 \(i, j\),扫到 \(j\) 时,将 \(L[i] < a[j]\) 的 \(i\) 在 \(a[i]\) 处加 \(dp[i]\),询问 \(\min(a[j], R[j]) - 1\) 前缀和。
10.10 模拟赛总结
代码源 CSP-S 模拟赛 Day 17。这把打的爽,但是出成绩很憋屈!!!
7:51 开赛,T1 给定 \(n, m, a, b, c, d\),求从 \((0, 0)\) 走到 \((n, m)\),不经过左下角为 \((a, b)\)、右上角为 \((c, d)\) 的闭矩形的方案数。我竟然 \(5\) 分钟秒了,注意到 \(n \le 10^3, m \le 10^6\),从 \(n\) 入手,预处理组合数,设 \(F(x_1, y_1, x_2, y_2)\) 表示从 \((x_1, y_1)\) 走到 \((x_2, y_2)\) 的方案数。考虑中间节点为 \((a, d)\),不限制;然后是 \((i, d)(i \in [0, a))\),限制到达此处后必须向上(防止计重);然后是 \((c, b)\),不限制;然后是 \((i, b)(i \in (c, n])\),限制到达此处前必须位于 \((i, b - 1)\)(防止计重)。
因此,答案为 \(F(0, 0, a, d) \times F(a, d, n, m) + \sum\limits_{i \in [0, a)} F(0, 0, i, d) \times F(i, d + 1, n, m) + F(0, 0, c, b) \times F(c, b, n, m) + \sum\limits_{i \in (c, n]} F(0, 0, i, b - 1) \times F(i, b, n, m)\)。感性理解很对,也是直接过大样例了。
8:11 提交 T1,期望得分 \(100\) 分。T2 是说,给定无向带权树和 \(s, t\),一次操作选择边 \((u, v)\),保留该边,将与 \(u\) 相连的其它边 \((u, x)\) 改为 \((v, x)\)。对于每个 \(k \in [0, n]\),求进行 \(k\) 次操作后 \(s\) 到 \(t\) 的路径权值和的最小值。
很快就有思路了,设 \(s\) 到 \(t\) 初始有 \(len\) 条边,则 \(k < len\) 时,必然要选择路径上的边,操作可以使其变得不在路径上,即边权和减少它。于是将 \(len\) 条边排个序即可。之后的操作,必然有 \(len = 1\)(因为不可能一条边都不剩)(剩下的是原路径上最小边,称为主边),然后又发现可以通过两次操作将两条相邻的边调换。于是这个操作大概就理解他是干啥的了:一次操作删除一条边,并将端点直接接上;两次操作交换两条相邻边。虽然子树换来换去,但是感觉不是很重要。同时,注意到在前 \(len - 1\) 次操作时,可以做到把路径上的点以及其非路径上的子树全部改接到 \(t\) 身上,那么对于非主边,设其到 \(s\) 或 \(t\) 的最短距离(指边数)为 \(dep\),这个是好求的,那么就需要 \(dep + 2\) 次操作将该非主边移到主边相邻处,然后交换它们。DFS,扫到一条边时,对答案更新一下即可。注意最后要令答案 \(ans[i]\) 对 \(ans[i - 1]\) 取 \(\min\)。
9:24 提交 T2,期望得分 \(100\) 分。大样例好水,都是链,最大的一个是个三叉戟。感觉可能寄。
T3 是说,\(n\) 个数选择若干个,使得相邻两个选择的位置(设为 \(i, j\))满足:\(\operatorname{popcount}(a_j \& a_i ) = k_i\)。求最多选择数量及一种方案。很容易想到 \(O(n^2)\) 的 DP,然后 \(2^8\) 应该很好做但是我不会,\(a_i = i\) 我也不会。但是我觉得 DP 可以优化,赛后 得知这是个 trick(dhw 说的),见过的可以直接秒。我根本不会,但是我观察样例发现,构造方案中,相邻两个数差很小,于是大胆优化,只枚举之前 \(\sqrt n\) 个,赌数据水。
11:24 提交 T3,期望得分 \(23\) 分。
T4 直接 BFS 暴力应该是好做的呀,但是调了一万年没调出来,最后匆匆交上去。
11:51 出成绩:\(100 + 35 + 40 + 11 = 186\)。你是说我 T2 挂了???观察了一下代码,发现本来是需要把路径上的点以及其非路径上的子树全部改接到 \(t\) 身上的,但是我怎么只把路径上的点改接了???这能过所有大样例???(好吧链确实能过,也只能过链)。痛失 \(65\) 分。
然后 T3 是个 trick,有暴力 \(O(n2^{20})\) 的 DP 做法,就是存储 \(best[x]\) 表示 \(a[i] = x\) 的 \(dp[i]\) 最大值,需要 \(O(2^{20})\) 求答案,\(O(1)\) 更新 \(best\),优化就是复杂度均摊。称高位表示前十位,低位表示后十位。记 \(a[i]\) 高位为 \(H\),低位为 \(L\)。设 \(best[h][x][t]\) 表示已处理过的,高位为 \(h\),低位对 \(x\) 按位与后,有 \(t\) 个 1,\(dp[j]\) 最大的 j$。这样可以做到 \(O(2^{10})\) 求答案和 \(O(2^{10})\) 更新 \(best\)。
如果 T2 没有少这一句,我就是 \(251\) 分,能进前五十了。。。
10.13 模拟赛总结
代码源 CSP-S 模拟赛 Day 18。
7:54 开赛。在尝试了一万年 T1 后,没 in 出来。只写了 \(T = 1\) 且所有字符串只包含一/两种字符的性质。
注意到 T4 暴力分非常多,\(n \le 7\) 直接暴搜,\(k = 2\) 是模拟冒泡排序,\(k = n - 1\) 发现只能对 \(1, 2\) 操作,而且必然是交替操作,最终得到 \(2n\) 个序列,排序求最小字典序。然而我忘了 \(n \le 500\) 了,可以暴力但我直接就是研发出了 \(O(n)\) 做法。未来的我早已得知自己的结局。
11:30 提交 T4,期望得分 \(35\) 分。没错,我只剩二十四分钟了。T3 暴力很简单,按权值从小到大考虑 \(w_x\),枚举 \(i\) 得到 \(j = x \oplus i\),若 \(j \le n\),则并查集合并。
11:42 提交 T3,期望得分 \(25\) 分,认为 \(w\) 随机生成应该能过,应该是很快就合并完了,直接退出。T2 直接输出原串,万一有性质呢。
11:54 出成绩:\(30 + 0 + 25 + 10\),但是 T1 两种字符的挂了,但是答案不超过 \(10\) 的过了。感觉很神秘。T4 挂成 \(10\) 分,\(k = 2\) 和 \(k = n - 1\) 因为写的太复杂所以挂了。
T1 我这辈子都想不到。先转化成三进制 \(0, 1, 2\)(为什么我想不到呢?因为我想成 \(1, 2, 3\) 了,所以没有后续),于是一次操作就是,将 \(b\) 改为 \((a + c - b) \bmod 3\)。考虑差分数组(同样模 \(3\),原本第一个元素作为数组第一个元素),操作前是 \(b - a, c - b\),操作后是 \(c - b, b - a\),因此一次操作等价于交换相邻两项。无解即起始和最终状态的差分数组元素不同或第一个元素不同,最小代价即对起始差分数组元素求一下其在最终差分数组的位置(例如起始差分数组为 \(01201\),最终差分数组为 \(12100\),则位置为 \(41253\)),然后对位置求逆序对数,即为将起始差分数组变为最终差分数组的最小操作次数。
T2 是保序回归,我用左偏树实现了。“长度为 \(p\) 的区间有至少 \(q\) 个 \(1\)”转化为“第 \(i\) 个 \(0\) 和第 \(i + (p - q)\) 个 \(0\) 距离大于 \(p\)”。令 \(org_i, pos_i\) 分别表示初始第 \(i\) 个 \(0\) 的位置(已知),最终第 \(i\) 个 \(0\) 的位置(未知)。令 \(d = p - q\),则 \(pos_{i + d} - pos_i \ge p\)。显然 \(\%d + 1 = r\) 的同余类内部有影响,同余类两两不影响。枚举 \(r \in [1, \min(d, m)]\),做替换 \(y_t = pos_{r + t * d} - t * p\),可得 \(y_t \le y_{t + 1}\)。同时 \(y\) 有上下界:由于 \(i \le pos_i \le n - (m - i)\),其中 \(m\) 为 \(0\) 的个数,所以 \(L = r \le y_0 \le y_1 \le \dots \le y_k \le n - (m - (r + k * d)) - k * p = R\)。
设 \(v_t = org_{r + t * d} - t * p\),构造单调不降序列 \(y_t\)(值域为 \([L, R]\))使得 \(\sum |v_t - y_t|\) 最小,把 \(v_t\) 压到 \([L, R]\)(小于 \(L\) 则等于 \(L\),大于 \(R\) 则等于 \(R\)),然后左偏树实现保序回归即可,最后 \(0\) 的位置即为 \(y_t + t * p\)。关于为什么不同的同余类之间不会有重合的 \(0\) 的位置,题解给出的说法是因为保序回归有偏序不变性,约束越松解越小,首尾增删只会单调影响解。
T3, T4 仍然不会。
10.15 模拟赛总结
代码源 CSP-S 模拟赛 Day 19。打的还是很不好。
7:55 开赛。T1 说,每次操作许选择一个数,令其他 \(n - 1\) 个数减一,自己加 \(n - 1\),操作一次后不能有负数,求使数组 \(a\) 变成 \(b\) 的最小操作次数。发现和不变,因此先判断和是否相等。又想了一会,还是从次数入手,构造最优操作次数 \(x[i]\),设 \(X = \sum x[i]\)。必要条件:\(b[i] = a[i] + x[i] * (n - 1) - (X - x[i]) = a[i] + x[i] * n - X\)。稍微推一下,\(a[i] - b[i] + x[i] * n = X\),注意到如果对所有数都进行一次操作,等价于没有操作,因此必然存在一个位置不进行任何操作,那个位置 \(x[i] = 0\),则 \(X\) 就是那个位置的 \(a[i] - b[i]\)。显然取最大 \(a[i] - b[i]\) 即为答案。但是这不满足充分性,因为可能中途遇到有多个 \(0\) 的情况,此时操作不下去。然后就是开始疯狂思考如何判断 \(-1\)。
中途没想出来,于是去看 T2 了,大概推了推,有用的模数序列必然是总序列的前缀最小值序列,最后一个数是 \(l\)。只考虑一个递减子序列作为模数序列,且最后一个数是 \(l\)。发现第一个数很重要,它限制了循环节长度,也就是任何数模完第一个数 \(m\) 后都是 \(0 \sim m - 1\)。那么暴力就写了,\(O(n)\) 枚举第一个数 \(m\),\(O(2^{n})\) 枚举子序列,对 \(0 \sim m - 1\) 每个数求它走完一遍的结果,即为题中所说的函数循环节(但是不一定最短),需要判断该结果是否有更小循环节(KMP 即可),没有则存入 set,答案为 set 大小。
11:31 提交 T2,期望得分 \(25\) 分。T1 也是终于想出来了判 \(-1\) 了,考虑肯定要先对 \(a[i]\) 小的进行操作(不然更容易出现无法操作的情况),因此根据 \(X\) 逆推每个位置的 \(x[i]\)(\(x[i] = 0\) 的不要它),按 \(a[i]\) 排序后,先对第一个 \(i\) 进行一次操作,把它先加大点防止后面被减成负数,然后第二个,以此类推,若当前是第 \(j\) 个,它的 \(a\) 小于 \(j - 1\),即进行完之前的操作后自己成负数了,那就是无解。否则,都进行一次操作后没有出现无解,那之后更不可能有无解了。
11:46 提交 T1,期望得分 \(100\) 分。
11:55 出成绩:\(70 + 25 + 0 + 0 = 95\) 分。T1 挂了???lzf 看了眼说我一开始多加了个特判:\(a\) 中 \(0\) 的数量大于 \(1\) 时直接无解。这肯定是错的呀,因为有可能 \(a = b\)。铭记特判不能乱加。
T2, T3 题解都还挺好懂,T2 模拟样例 \(l = 2, r = 5\)(左侧是保留值,右侧下标是除以第一个保留值的余数,值是该余数跑完一遍后的结果):
5432 01000
532 01001
542 01010
52 01010
432 0100
42 0101
32 010
2 01
比如第一组 5432,% 5 = 0 时结果为 0,% 5 = 1 时结果为 1,以此类推,结果为 01000。
对于 42,其结果 0101 具有周期 01,和 2 的结果 01 计重,因此 42 不算入答案。同时,542 和 52 的结果完全重复,只计一次。
对于结果,注意到从下标 \(i\) 到下标 \(i + 1\),值要么加一(保留值 \(\le i\) 或 \(> i + 1\)),要么变为 $0(保留值 \(= i + 1\))。发现前 \(l\) 个数必然是 \(0, 1, \dots, l - 1\)(最小保留值为 \(l\)),之后就是若干段从 \(0\) 开始加到某个数 \(t\) 的区间(即 \(0, 1, \dots, t\)),要求长度 \(\le l\)。
显然,下标是保留值的必然值为 \(0\)(区间开头),但是不代表值为 \(0\) 的下标必然是保留值(如 52)。统计的是结果的方案数,从保留方案入手并不好做。正难则反,设第一个保留值为 \(M\),考虑任意一种划分 \([0, M)\) 且满足每个划分区间长度 \(\le l\)(第一个区间长为 \(l\)) 的方案,必然存在一种保留方案。为什么呢?只保留每个划分区间(第一个除外)开头的下标即可,最终结果必然为该划分方案。
因此,设 \(g[i]\) 表示将长为 \(i\) 的区间划分成若干个长为 \([1, l]\) 的区间的方案数。显然有 \(g[0] = 1, g[i] = \sum\limits_{j = max(i - l, 0)}^{i - 1} g[j]\)。可以 \(O(r)\) 实现。那么,钦定第一个区间长为 \(l\),后面的方案数就是 \(g[M - l]\)。
这样只能防止“结果完全重复”时计重,但是若结果具有周期,这样仍会计重。这里的周期指恰好的周期,可以证明全体周期必然是最小周期的倍数。因此,设 \(f[i]\) 表示最小周期为 \(i\) 的方案数。显然有 \(g[i - l] = \sum\limits_{j | i, j \ge l} f[j]\)(这里的 \(i\) 代表 \(M\),即总区间长度)。\(j | i\) 是因为周期要恰好,\(j \ge l\) 是因为周期不可能小于第一段长度。
可以初始令 \(f[i] = g[i - l]\),然后从小到大枚举 \(i\),我们希望 \(f[i]\) 已经被减去那些满足 \(j | i, j < i\) 的 \(f[j]\),因此之前枚举到的 \(i\) 令 \(f[2 * i], f[3 * i], \dots\) 都减去 \(f[i]\),这是调和级数级的。最后答案为 \(\sum f[i]\)。
T3 说,给排列,设 \(f(l, r)\) 表示将区间 \([l, r]\) 染红蓝色,使得红色递增、蓝色递增,的方案数,每次询问 \(L, R\),求 \(\sum\limits_{L \le l \le r \le R} f(l, r)\)。
若 \(i < j, p_i > p_j\),则 \(i, j\) 必须异色,令其连边。得到逆序对图,若可以合法二分染色,令连通块数为 \(k\),则方案数为 \(2^k\),因为每个连通块都有两种染色方案;否则,方案书为 \(0\)。
不合法的充要条件为存在 \(i < j < k, p_i > p_j > p_k\)。充分性显然,会有三元环。必要性:没有三个数递减时,把区间内的前缀最大值染红,其余位置染蓝,红色序列显然递增,蓝色序列若存在逆序对 \(i < j\),由于 \(p_i\) 不是前缀最大值,则必然存在 \(t < i\) 使得 \(p_t > p_i\),构成 \(p_t > p_i > p_j\),与条件矛盾,因此蓝色序列递增。
又注意到连通块一定是连续的一段:对于逆序对 \(i < j\),任意 \(t \in (i, j)\) 必然有 \(p_i > p_t \lor p_t > p_j\),因此区间属于同一连通块。
将询问离线到 \(r\) 上,从左往右扫描 \(r\),设 \(A_l = f(l, r), B_l = \sum\limits_{t = l}^r f(l, t)\),那么每次就是把每个 \(A_l\) 更新一下,然后把所有 \(A_l\) 加到 \(B_l\) 上,询问答案为 \(\sum\limits_{t = l}^r B_t\)。也就是,区间历史版本和。现在看怎么更新 \(A_l\)。
维护最后一个递增区间 \([s, r)\),二分出大于 \(p_r\) 的最小位置 \(b\),再令 \(k = r - b, v = p_b\)(若没有,则 \(b = r, k = 0, v = +\infty\))。当 \(s > 1\) 时,令 \(h = p_{s - 1}\)。
-
对于 \(l \in [b,r]\),\(A_l\) 区间修改为 \(2\)。因为,对于任意 \(t \in [l, r)\),有 \(p_t > p_r\),而 \(t\) 内部不存在逆序对,因此所有 \(t\) 仅向 \(r\) 连边,构成一个连通块且合法,方案数为 \(2\)。
-
对于 \(l \in [s, b)\),\(A_l\) 区间乘 \(2^{1 - k}\)。因为,原本递增区间内部不存在逆序对,即有 \((b - l) + k\) 个单点连通块。对于任意 \(t \in [b, r)\),有 \(p_t > p_r\),因此所有 \(t\) 仅向 \(r\) 连边,删除 \(k\) 个连通块,构成一个合法连通块,方案数乘 \(2^{1 - k}\)。
-
当 \(s > 1\) 时,对于 \(l \in [1, s)\),\(A_l\) 区间乘 \(\lambda\)。
-
若 \(h < p_r < v\),基本同第二种情况,\(\lambda = 2^{1 - k}\)。
-
若 \(p_r < h < v\),\([b, r)\) 和 \(r\) 连成一个连通块,\(r\) 又和 \(s - 1\) 连成一个连通块,原本 \(s - 1\) 就和 \([s, b)\) 处于一个连通块,因此相当于直接删除 \(k\) 个连通块,\(\lambda = 2^{-k}\)。
-
若 \(p_r < v < h\),此时 \(s - 1, b, r\) 构成 \(h = p_{s - 1} > v = p_b > p_r\),连通块不合法,\(\lambda = 0\)。这里不用担心 \(b = r\),因为此时 \(v = +\infty\),不会进入该情况。
-
区间修改等价于区间乘 \(0\)、区间加修改值,因此需要对 \(A\) 进行三段修改,支持区间乘、区间加、维护历史版本和。吉司机线段树即可。
T4 是把邻边排序,贪心选择 \(i\) 和 \(2k - i + 1\),并查集维护环连通性,连通两个环需要将两条边交换,具体到边上就是将 \((i, 2k - i + 1), (i + 1, 2k - i)\) 互换为 \((i, 2k - i), (i + 1, 2k - i - 1)\),边权为 \(w_{i + 1} + w_{2k - i - 1}\),将此类新边存下排序,类似 Kruskal 跑一遍即可。
10.17 模拟赛总结
代码源 CSP-S 模拟赛 Day 20。今日关键词:非降序。
7:54 开赛。T1 对数组操作:选择偶数 \(k\),令 \(a_i(i \in [1, k])\) 加上 \(i\),求使数组变为非降序的最小操作次数。尝试差分数组 \(b_i = a_{i + 1} - a_i\),发现就是选择偶数 \(k\),令 \(b_i(i \in [1, k))\) 加上 \(1\),\(b_i\) 减去 \(i\),求使数组无非负数的最小操作次数。\(n\) 是偶数直接选择 \(n\) 操作 \(\max(0, \min b_i)\) 次即可,考虑奇数。发现操作是无序的,钦定从后往前操作,维护目前的累加标记 \(add\),先令 \(b_i \leftarrow b_i + add\),再判断 \(b_i\) 是否为负数,若是说明无法成功。然后若 \(i\) 为偶数则操作 \(\frac{b_i}{i}\) 次,加入 \(add\)。竟然大样例都过了,观察一手发现怎么奇数全是 \(-1\) 啊,上心下心。
8:33 提交 T1,期望得分 \(100\) 分。T2 将数组划分成若干段,从左往右操作,初始序列为空,将当前段插入到当前序列的任意位置,求使最终序列非降的最少划分段数。段内显然非降,设段 \(p = [l, r]\) 的值域为 \([x_p = a_l, y_p = a_r]\),由于后段插入进前段,不能存在段 \(q(q < p)\) 内有 \(a_i \in (x_p, y_p)\)。反之,对于 \(a_i\),需将段 \(p\) 划分为值域 \([x, a_i]\) 和 \((a_i, y]\) 两段。段 \(p = [l, r]\) 合法当且仅当 \(\forall i < l, a_i \not\in (x_p, y_p)\)。因此,从左往右扫一遍即可,值域树状数组求 \((x_p, y_p)\) 之和。
9:12 提交 T2,期望得分 \(100\) 分。T3 给定有向带权图和 \(S\),\(Q\) 次询问 \(U\) 到 \(V\) 必须经过 \(S\) 且路径边权非降时的路径末边权的最小值(路径无边时为 \(0\),无法到达时为 \(-1\))。设 \(f[u]\) 表示 \(u\) 到 \(s\) 的最小时刻。\(f[s] = 0, f[u \ne s] = +\infty\)。边权降序,加入新边时即可保证之前的边都允许通过,从而 \(f[v]\) 有值时保证路径的边权非降。当 \(v = s\) 时,\(f[u] = \min(f[u], w)\);否则,\(f[u] = \min(f[u], f[v])\)。注意 \(w\) 相同的边,设数量为 \(T\),要跑 \(T\) 遍。不同的 \(f[u]\) 至多 \(\min(n, m, \max w)\) 个(取决于 \(v = s\) 时的 \(w\)),设其去重升序为 \(f_1, f_2, \dots, f_k\)。设 \(pos[f_i] = i\)。设 \(g(u, i)\) 表示从 \(s\) 出发,起始时刻为 \(f_i\),到达 \(u\) 的最小时刻。\(g(s, i) = f_i, g(u \ne s, i) = +\infty\)。询问答案即 \(g(v, pos[f[u]])\)。边权升序,当且仅当 \(g(u, i) \le w\) 时,\(g(v, i) = \min(g(v, i), w)\)。时空爆炸,但是不会优化,就这样吧。
10:58 提交 T3,期望得分 \(52\) 分。T4 感觉可以 \(O(n^2)\) 建图,边权为相交区间,那么删除区间就是删除那些边权被删除区间包含的边,然后跑最大独立子集问题,转化为补集最大团。但是怎么删除区间就被卡住了,最多我也就会个 \(2^n\) 枚举,但是只有 \(6\) 分,懒得写了。然后回到 T3 优化,还是不会。
11:54 出成绩:\(70 + 100 + 0 + 0 = 170\)。T1 挂了 \(30\) 分,经过一万查错后发现,操作 \(\frac{b_i}{i}\) 次得到的是最大操作次数,所以它只能正确判断 \(-1\),不能得到答案!需要维护一个前缀最小值,中途判断下一次是否能直接使前缀最小值非负。
T3 思路倒是没问题,但是时间复杂度错了呀,最坏是 \(O(m^2)\) 的,根本过不去任何点。目前还是不会 T3, T4,dmy 题解讲的是人话吗?
10.19 模拟赛总结
jsy 模拟赛,放的是 2024 年洛谷 scp-s 模拟赛的题,难度绿蓝紫紫。
8:00 开赛,T1 秒了,考虑最后留下一个不超过 \(6 \times 10^5\) 的数字,花费它的代价,那么需要判断它是否在原串中出现过,不断二分即可,更新答案也是好做的。
8:35 提交 T1,期望得分 \(100\) 分。T2 最优肯定要两个不同的字符匹配,然后不会再增加数量了,多余的字符就分配给原来的。问题在于怎么找到一种方案把它们匹配上,这里被卡了很久,陷入思维误区了,一直以为同种字符一旦开始和别人匹配就要匹配完,导致与正解擦肩而过了。中途想到过正解是把数量最多的字符和次多的字符匹配,但是由于思维误区导致想成了把次大那一堆匹配完。后面修了很久根本没有获得任何分数。
T3 没啥入手点,猜测转化成差分,点权转化成 \(d_u = a_u - a_{f_u}\),操作一是单点加,操作二是叶子祖先链外的子节点 \(d[i]\) 加 1,\(d[1]\) 减 \(1\),因此除 \(1\) 号点外不能有大于 \(0\) 的点,写个特判祈求点儿分。
11:28 提交 T3,随机得分。T4 第一眼没想到 \(O(n^2)\) 的暴力,准备写 \(O(n^3)\) 时忽然想到维护一下已空节点集合和与其相邻的非空节点集合即可,就是 \(O(n^2\log n)\) 的。
11:46 提交 T4,期望得分 \(32\) 分。T2 退而求其次,把原本代码微调了一下,能够获得“\(k\) 不是最大时获得 \(40\%\) 的分数”。
11:55 提交 T2,期望得分 \(40\) 分。
12:00 出成绩:\(100 + 50 + 0 + 32 = 182\) 分。T3 读入 \(a_u\) 是 \(10^{12}\) 级别,我根本没开 long long,挂成蛋了。赛后根据通过 T2 的 mxf 所述,我才知道可以匹配一次就重新求一遍最大字符和次大字符,没有必要一直匹配完一堆。
T3 还挺好,我转化成差分是没问题的。发现操作二很重要,若 \(d_1 \le 0\) 则只需操作一,否则需要用操作二使 \(d_1\) 减至 \(0\),然后用操作一,在此过程中不能有 \(i > 1 \land d_i > 0\)。设 \(dp_i\) 表示以 \(i\) 为根的子树,操作二的最大次数,对 \(i > 1\) 设 \(lim_i = -d_i\) 表示影响到 \(i\) 的操作二的最大次数。设 \(v\) 对 \(u\) 贡献 \(c_v\) 次,令 \(s = \sum c_v\),显然 \(s\) 满足单调性,\(dp_u\) 为最大的 \(s\)。一方面 \(c_v \le dp_v\),另一方面 \(s - c_v \le lim_v\),即 \(\max(s - lim_v, 0) \le c_v\)。因此,\(\max(s - lim_v, 0) \le c_v \le dp_v\),二分 \(s\) 时取 \(l = 0, r = \min(dp_v + lim_v)\)。若 \(c_v\) 都取最大值 \(dp_v\) 时,其和仍然 \(< s\),则该 \(s\) 不合法;都取最小值同理。其余 \(s\) 合法。叶子节点有 \(dp[u] = +\infty\)。
T4 有点借鉴支配对思想,设 \(lst_i\) 表示想要让 \(a_i\) 上场,至少要对 \(lst_i \sim i\) 操作。暴力求得话就是,若 \(a_i\) 直接连向 \(1\) 则 \(lst_i = 1\),否则 \(lst_i\) 是其连向点中得最大 \(lst\)。考虑优化,根号分治,若该点出度 \(\le sqrt n\) 则暴力求,否则不暴力求,然后每个点对出度 \(> \sqrt n\) 的父节点更新即可。注意每个点作为子节点的答案和作为父节点的答案要用两个数组存,比如先弄 \(u\),更新了父节点之一 \(f\),再弄一个连向 \(f\) 的点 \(u'\),此时 \(lst[u']\) 应该被 \(f\) 作为父节点的数组更新,而不是被 \(f\) 作为子节点的数组更新。
求完 \(lst_i\),对于询问离线到右端点上,从左往右扫一遍就行了,求的是 \(lst \ge l\) 的数量。
总结就是:
不开 long long 见祖宗!
10.20 模拟赛总结
代码源 CSP-S 模拟赛 Day 21,based on 很大的西安区域赛。
7:57 开赛,T1 很快想到三分做法,感到不可思议,真的有这么模板吗?8:20 测大样例,竟然只错了一个,直接猜测要分 \(x, y\) 大小,若 \(x > y\) 再三分,否则直接就是 \(x \cdot \max b_i\),直接过大样例了。
然后开始拍,想到了 \(O(n |V|)\) 的暴力就是把三分改成在值域上暴力枚举。拍拍拍,第一组就错了。打表得知它根本不具有凸性或凹形!!!
这不废了。然后想到了一段连续的 \(calc(x)\) 是一次函数,那么会对答案有贡献的只可能是每个 \(calc(b_i)\),就可以优化到 \(O(n^2)\) 了(指暴力)。这里期望得分 \(60\) 分。后面一直僵持到了 10:17,放弃 T1 了。中间没有放弃传统,先去打 T4 特殊性质 \(a_i \le 1\),获得了 \(15\) 分的好成绩。
放弃 T1 后取看 T2, T3 的暴力,T2 直接暴搜枚举 \((m, k)\) 能有 \(10\) 分,然后打表观察 \(a_i \le 1\) 的性质无果。T3 \(O(n!)\) 枚举排列判断合法也是好做的,这样就是 \(25\) 分了。
11:57 出成绩:\(60 + 10 + 25 + 15 = 110\) 分。赛后得知 lzf 用三分骗过去了???暴力枚举前后各 \(32\) 个,对中间的三分得到位置并向左向右各扩展 \(16\) 个,这代码源不卡它???什么时候这么水了???
看题解没懂,听 Air 讲 T1。
若 \(b[i - 1] - (a[i] - a[i - 1]) \ge b[i]\),则 \(b[i]\) 没用,直接扔掉。
设 \(f_i(x) = \max(0, b[i] - \max(0, b[i - 1] - (a[i] - a[i - 1]) - x) - x)\) 表示初始金属化 \(x\) 级,从 \(i - 1\) 到 \(i\) 的最少覆甲次数。
\(f_i(x)\) 关于 \(x\) 呈现三段式(非负常数、降一次函数、0),拐点分别是 \(x_1 = b[i - 1] - (a[i] - a[i - 1]), x_2 = x_1 + b[i]\)。可以发现它一直都是一次函数,即:
-
当 \(0 \le x < x_1\) 时,\(k = 0, b = max(0, b[i] - max(0, b[i - 1] - (a[i] - a[i - 1])))\)。
-
当 \(x_1 \le x < x_2\) 时,\(k = -1, b = b[i]\)。
-
当 \(x_2 \le x \le (2 \times 10^9)\) 时,\(k = 0, b = 0\)。
设 \(calc(x) = \sum\limits_{i = 1}^{n} f_i(x)\),答案为 \(\min\limits_{x = 0}^{2 \times 10^9} calc(x)\)。
由于一次函数相加还是一次函数,因此拐点会将 \(calc(x)\) 函数划分为 \(O(n)\) 段一次函数,每一段的 \(k, b\) 就是覆盖这一段的 \(f_i(x)\) 的 \(k, b\) 之和。
考虑将拐点离散化(包括 \(0, 2 \times 10^9 + 1\)),对于同组拐点 \(x_1, x_2\) 会在 \([0, x_1)\)、\([x_1, x_2)\)、\([x_2, 2 \times 10^9 + 1)\) 分别贡献三种值,差分即可。相邻两个拐点之间的段的 \(k, b\) 即为对其贡献的 \(k, b\) 之和,在两个端点处求 \(calc(x)\) 最小值即为本段最小值,得到全局最小值。
关于 T2,它死了。
10.21 模拟赛总结
qy 模拟赛。今天的题略有点水。未来的我已经得知本场比赛难度绿绿青青。
8:00 开赛,T1 看到它还考虑了一会儿,认为不应该这么简单,但是你都 \(n \le 100\) 了真不暴力做吗?考虑长度最大的两个串,一个是前缀,一格时后缀,check 一下即可。
8:17 提交 T1,期望得分 \(100\) 分。T2 我想着不会还很简单了吧,所以又思考了一会儿,最后得出结论就是乱写写就过了。考虑一个位置必然是一直走和它奇偶性相同的点,直到能够一步走到奇偶性不同的点。因此对奇偶性相同的点之间建边,得到奇偶两张图,从能一步走到奇偶性不同的点的那些点出发,跑多元最短路即可。
8:39 提交 T2,期望得分 \(100\) 分。T3 很快猜到结论,先跑最小生成树,对于非树边求其端点在树上路径的最大边权,若等于该非树边的边权,则该非树边需要操作一次。是否有可能大于呢?显然不可能,不然不符合最小生成树。类似倍增求 LCA 取求这个东西。
8:59 提交 T3,期望得分 \(100\) 分。当我以为我写的够快了时,Air 忽然向 qy 说他 AK 了,吓哭了。然后 cyz 也说他 AK 了,惊。
T4 卡了会,第一个问题是怎么求长为 \(n\) 的合法括号序列数,赛后得知可以卡特兰数,但是我不会呀,我用 DP 做了,不考虑限制对,设 \(dp[i][j]\) 表示考虑 \(1 \sim i\),待匹配的 ( 数量为 \(j\) 时的方案数。
-
选择 \(s[i] = (\),要求 \(j > 0\),有 \(dp[i][j] \leftarrow dp[i - 1][j - 1]\)。
-
选择 \(s[i] = )\),要求 \(j < n\),有 \(dp[i][j] \leftarrow dp[i - 1][j + 1]\)。
竟然一遍过样例。之后考虑限制对,思考了一段时间,想到这样一个样例:

红色内部是独立的,蓝色内部是独立的,因为它们不能有和外面匹配的括号。黄色内部是独立的(指这三段并一块)。发现同属一个独立段的,它的前缀和相同。于是记录目前的前缀和以及 \(cnt_{sum}\) 表示前缀和数量,在左括号处记录它的前缀和(也就是和它同级的独立段前缀和)的数量,相应的右括号处求左括号的前缀和的数量减去左括号处的那个值,得到区间内这个前缀和的数量。它们贡献到答案里。最后前缀和为 \(0\) 的同属于一个独立段,算到答案里。
10:18 提交 T4,期望得分 \(100\) 分。此时我觉得我也 AK 了,赶忙找 qy。然后被得知我挂了前三道。合着我就 A 了 T4?我怎么打上 IOI 了呢。
T1 对拍无果,想了想发现我写的很假呀,它只判断了前缀合法,没有判断后缀合法。于是重写了一版,并于 11:06 提交。期望得分 \(100\) 分。
T3 对拍小数据有错,然后找了找发现我在求路径最大边权时,最后返回了 max(res, maxw[u][0]),只考虑了 \(u\) 的父亲边,没有考虑 \(v\) 的父亲边。我糖了。11:43 提交 T3,期望得分 \(100\) 分。
T2 找了很久,确切的说之前一直在对拍,没拍出来,找也找不到,qy 调侃说这我估计一辈子找不到。我开玩笑说万一是 CE 呢。中间还找到了一个问题,Dijkstra 跑多元最短路时没用到 vis 数组,那不成 SPFA 了吗,但是这应该不是最大的问题。
我放弃了。出成绩了:\(100 + 0 + 100 + 100 = 300\),喜提机房最低分。T2 真的 CE 了,原因是:
笑点解析:
以后再也不用 inline 了,卡那点常干啥。
10.22 模拟赛总结
代码源 CSP-S 模拟赛 Day 22,四道题分别是 Csps, cSps, csPs, cspS。
7:56 开赛。T1 应该是黄,秒了,先把最优情况求出来,就是在原序列中分出来若干个不相交区间,对其内部排序后全局非降。和之前一道题有点像,从前往后,栈维护每个块的最大最小值,若当前与栈顶值域相交,则合并。得到这些区间后数量 \(cnt\) 可能 \(> k\),此时对其 \(cnt - 1\) 个间距排序,取最小的 \(k - cnt\) 个算入答案(可以理解成区间合并)。
8:38 提交 T1,期望得分 \(100\) 分。之所以这么晚是因为有点不敢信这是 Div.1。然后 T2 给我来了当头一棒。思考半小时无果,转战 T3。感觉自己能糊出来 \(O(n^2)\) 做法而且好优化?认为要存储 1000... 状物,对连续的 111... 直接操作。发现大样例过不去,又认为要按顺序,能合并两个 1000... 就合并,最后再把 11 合并,还是过不去那个样例。最后手算了一下,得出没有这样的必胜策略。假完了。
时间来到 11:00,不敢奢求什么分了,赶紧写了些暴力,比如 T2 的 \(O(n!)\),T3 的预处理 \(2^{11}\) 种情况,T4 的输出 1。
11:56 出成绩:\(100 + 15 + 10 + 1 = 126\) 分。Air 在最后十分钟极限过了 T2,听他讲什么有向图拓扑序转为树拓扑序,根本听不懂。
但是题解很好懂,一万个区间 DP,状态设出来后还挺自然,设 \(S[l][r][t]\) 表示将一组数放到 \((l, r)\) 内(不含左右端点),钦定它们小于左右端点的值,满足内部约束,在 \(t\) 轮及以内消除完 \((l, r)\) 的方案数。相应的,设 \(D[l][r][t]\) 是恰好第 \(t\) 轮消除完 \((l, r)\) 的方案数,要求 \(t \le r - l - 1\)。初值 \(S[l][l + 1][t \ge 0] = 1, D[l][l + 1][0] = 1\),其余为 \(0\)。枚举区间内部最大值位于 \(m\),转移:
设 \(L[i]\) 表示将一组数放到 \([1, i]\) 内,钦定 \(i\) 是最大值,满足内部约束的方案数。相应的,设 \(R[i]\) 表示 \([i, n]\)。
若 \(a[1] = 0 \lor a[1] = -1\),则初值 \(L[1] = 1\),同理 \(R[n] = 1\)。仅对于 \(a[i] = 0 \lor a[i] = -1\) 进行转移,枚举前/后缀最大值位于 \(j\),转移:
最后,枚举全局最大值位于 \(i\),答案:\(\sum\limits_{i = 1}^{n} C(n - 1, i - 1) \times L[i] \times R[i]\)。
T3 是结论题,只关注 1010...01 串(注意必须以 1 开头/结尾),称为特殊串,它们内部无法操作,设共 \(k\) 段,长度为 \(b_{1 \sim k}\),设 \(S\) 为其和,\(M\) 为其最大值,可以证明操作后 1 的个数最小值为 \(\max(S \bmod 2, M - (S - M))\),而且必然可以达到,因为相邻的特殊串之间要么没有 0,要么有 \(\ge 2\) 个 \(0\),于是必然可以将左串右端 1 和右串左端 1 和之间的 0 合并为 0,从而减少两个 1,并且这样操作不会改变 \(S\) 奇偶性,即 \(S \bmod 2\) 不变。然后考虑最长段,外面 1 数量为 \(S - M\),它们和内部 \(M\) 个 1 匹配,最后剩下 \(M - (S - M)\) 个 1。当然如果是负数,那说明最长串消除掉了,剩下的就可以一直合并,最后剩下 \(S \bmod 2\) 个 1。
设该值为 \(D(S, M)\),考虑求答案,若 \(k = 0\),则答案为 \(1\)(全为 0);若 \(k = 1\),则答案为 \(2 \cdot S - 1 [a_1 = 0] + [a_n = 0]\);否则,答案至多为 \(2 \cdot D(S, M) + 1\) 表示 \(a_1, a_n\) 都是 0 的方案,考虑 \(a_1\) 是 1 时,将它单独算一位,考虑剩下的位置,设 \(ML\) 表示令 \(b_1 \leftarrow b_1 - 1\) 后的最大 \(b_i\),则答案对 \(1 + 2 \cdot D(S - 1, ML) + 1\) 取 \(\min\);考虑 \(a_n\) 时 1 时同理,就是 \(1 + 2 \cdot D(S - 1, MR) + 1\)。\(S, M, ML, MR\) 都是可以随时维护的,因此可以 \(O(n)\) 做。
T4 是什么马氏链,第二类斯特林数,manboo 表示不会。
反思一下,现在再看 T2, T3,感觉都是可做的,但是 T2 赛时根本没往 DP 上想,T3 也并没有得出一个结论,还是思维力不够。
浙公网安备 33010602011771号