2025 山东四轮省集
这么多轮省集。
Day 0
Day 1
\(100 + 55 + 21\),\(\text{rk} 7\)。
T1
虚树是相邻两个点之间的链的并,直接跑区间链并即可。时间复杂度 \(O(n \log^2n + q\log n)\)。
T2
原题是 P8425。
容易发现要满足题中条件,最小值和最大值一定有一个在边上,否则整个序列就直接违反条件。所以可以用区间 DP 刻画上述过程:设 \(f_{l,L,len}\) 为要往 \([l,l+len-1]\) 填入 \([L,L+len-1]\) 这些数的最小代价。转移的时候直接选择一个最小/最大值扔到左边/右边即可。区间范围和要填的值域仍然是连续的。时间复杂度 \(O(n^3)\),可以获得 \(55\) 分。
将问题放到二维平面上考虑,一开始我们有 \([1,n],[1,n]\) 这个正方形,每一次我们把正方形四个方向的其中一个 L 形扣掉形成下一个,如果说这个 L 形对应的角上本来就有一个点那就节省 \(1\) 的代价。问最多节省多少代价。
问题就转化成了平面上有 \(n^2\) 个正方形,每个都形如 \([i \pm len,p_i \pm len]\),然后问你最多选出几个正方形使得他们排成一列,前一个包含后一个。
这里有一个观察,随机排列的答案是 \(O(\sqrt n)\) 量级的,大概不会超过 \(LIS + LDS\) 的长度。所以我们尝试以答案作为 DP 的下标。
设 \(f_{i,j,0/1/2/3}\) 为 \([i,p_i]\) 往某个方向的正方形如果要包含 \(j-1\) 个正方形,其边长至少是多少。转移是二维偏序,一层时间复杂度 \(O(n\log n)\)。总时间复杂度 \(O(n\sqrt n \log n)\)。
二维偏序也不大简单,以向右上为例,设右上方的正方形为 \([l,r],[d,u]\)。则要求 \(i < l \land p_i < d\),且 \(d - p_i > l - i\) 时,用 \(u - p_i\) 更新答案,否则用 \(r - i\) 更新答案。
这样限制还是很多。发现 \(d - p_i > l - i \land i < l\) 时 \(d > p_i\) 就自动满足了,此时只有两个限制,可以跑二位偏序转移,另一种情况同理,剩下三个情况同理,跑八遍二维偏序即可。
写了两部分之后直接急了,后面是贺的。
T3
原题是 P4255。
太毒瘤了。
1,2,4,5 据说爆搜配合一些估价函数就可以过。3 需要大量手玩。感觉不大可做。
杂题选讲
实际上是杂 *3500 选讲。
loj2832
在每两个栅栏和正方形的顶点之间建边,长度为两个线段之间的最短距离(即所有一个顶点到另一个线段之间的垂线和顶点之间的线段长度最小值)。
这样将正方形围起来的就一定是一个环,还要求是最小的。
但直接跑最小环可能会导致环没有把正方形包起来,考虑如何判断一个东西是否在多边形内,直接用射线法判断奇偶性即可。所以 Floyd 的数组只要多维护一维表示射线经过次数的奇偶性就行,时间复杂度仍是 \(O(n^3)\)。
计算几何不想写。
Day 2
\(100 + 50 + 25\),\(\text{rk} 23\)。
线下挂了很多分,线上是 \(100 + 60 + 100\) 然后 \(\text{rk} 10\) 的。前面全是 AK 的。T2,T3 数据都造水了,不好评价。
T1
容易发现 \(a\) 最后会变成 \((ab)^x a\),\(b\) 最后会变成 \(b (ab)^y\),\(x,y\) 可以 \(O(n)\) 递推,但是 \(x,y\) 太大了导致我们根本没法把数记下来直接快速幂。
发现对于排列 \((ab)\) 不断复合的过程中每个置换环是独立的,计算 \((x,y)\) 的过程中直接对每个置换环的长度分别取模,可以做到 \(O(nq)\)。
然后是经典结论,几个数加起来是 \(n\),那么他们最多只有 \(O(\sqrt n)\) 种。直接暴力可以做到 \(O(q \sqrt n)\)。
T2
QOJ11302
有点难,但是好像有一些假做法过了(我的 \(50/60\) 也是假算水的()。
关键结论:最终序列是固定的。
考虑从大到小枚举一个 \(k_0 \le k\)。将每一行 \(\ge k_0\) 的部分大小设为 \(b_i\)。
把行按照 \(b_i\) 降序排序。找到第一个满足 \(b_i < n-i+1\) 的位置,发现在这之前的对角线部分不得不是 \(k_0\),后面不可能是 \(k_0\),因此对角线 \(= k_0\) 的部分是确定的,并且构成 \(= k_0\) 部分有哪些行也是确定的。这样一层一层剥下去,这个图形就被分成了 \(k\) 层,当且仅当每一层答案都是奇数时,总的方案数才是奇数。
考虑每一层怎么做,发现对角线上必须是一样的数 \(x\),总的方案是 \(\sum\limits_{p} \prod{[b_{p_i} = i]}\)。众所周知积和式是不大能做的,但是在 \(\bmod 2\) 意义下这个东西等于行列式可以 \(O(n^3)\) 直接求。
这显然不够,发现每一行的 \(1\) 构成一段区间,所以有个结论是这个行列式满秩当且仅当对于每行的 \(1\) 区间 \([l,r]\) ,我们在 \([l-1,r]\) 之间连边,这些边构成一棵树。证明是不难的,就是构成环就完蛋了。所以只需要连边用并查集判断就行。时间复杂度 \(O(nk)\)。
T3
简单题,但是 pretest 太水了把我杀了。
题目条件相当于 R 需要在 B 构成的虚树中,然后区间的虚树就是相邻两个点的链的并,所以我们只需要考虑相邻两个点构成的链,以及单点就可以。
从左往右扫左端点,考虑一个位置在 \(x\) 上的 R 的合法性,如果有一对 B 在他左边并且 R 在他们之间的链上,我们称这个 R 为神了,就是不对右端点有任何限制;如果(没有神了并且)左右各有一个 B 并且在他们之间的链上,我们称之为特殊情况,此时 R 对右端点的限制是右端点不能在 \([x,pos_{B}-1]\) 之间(\(pos_B\) 是右边 B 的位置);如果上述条件都不满足,我们预处理出从每个 R 向右扩展第一个使其合法的位置(用颜色段均摊实现),记为 \(ed_x\) 此时对右端点的限制是不能在 \([x,ed_x - 1]\) 之间。称之为有限制。
发现一个位置从有限制到特殊情况到神了最多改变两次,我们只需记下他的状态然后每遇到一个新的 B 直接暴力找到需要改变的点就可以了。使用树剖线段树实现。对右端点的限制使用线段树,然后限制是区间加,最后看最小值是不是 \(0\) 并找到最靠右的最小值位置即可。时间复杂度 \(O(n \log ^2 n)\)。
Day 3
\(100 + 70 + 0\),\(\text{rk} 26\)。
这场坠机了,T2 差点 \(0\) 分,\(100\) 很简单但是没时间写了。
T1
考虑对于每个点求出其到 \(1\) 的最短路 \(f_i\),以及割掉其到 \(n\) 的最短路上的第一条边(也就是对 \(n\) 建出最短路树之后,\(i\) 到父亲的边)后到 \(n\) 的最短路 \(g_i\)。
求出这些之后就可以二分答案/Dijkstra 轻松求出答案,\(f_i\) 是简单的,考虑 \(g_i\) 怎么求。
下面的树说的都是 \(n\) 为根的最短路树。
发现 \(i\) 必须要走出子树才能到 \(n\),所以一定是 \(i\) 先沿树边走到子树内一点,在走一条非树边,在沿树边走回 \(n\)。对于一条非树边 \((x,y)\),相当于对于任意 \(z\) 在 \(x\) 到 \(y\) 的链上并且 \(z \neq LCA(x,y)\)。那么 \(dis_x + dis_y - dis_z + 1\) 可以更新 \(g_z\)。直接用可并堆维护,遇到已经失效的边直接从堆中删掉即可,还可以线段树合并/启发式合并。
T2
是 CF1510H(FJOI2022D1T1(笑) 的没有构造方案版,不难,但是我没写完,离比赛结束半分钟极限调完,然后树上背包就没时间改了。
区间形成树形结构。发现区间选的子段为空也没关系,最终肯定能调整成不为空。一个叶子节点一定是填满的。
我们把一个区间最靠左叶子节点的左边部分成为左边界,右边界同理。一个区间如果填过左边界,那么它上面的点就不会再填这里了。否则这个区间可以直接不填,由上面的点来填这个左边界,这样就避免了一些算重的问题,直接提前计算贡献,设 \(f_{i,k,0/1,0/1}\) 代表节点 \(i\) 所在区间,他的祖先中有 \(k\) 个填在这里面,左边界/右边界有没有填。转移直接 \(k\) 这一维树上背包,遍历所有的子节点,并对于一个空隙,只有在两边的边界都没有被填的时候才可以选择转移。最后决定填不填左右边界,都是平凡的。最后记得把 \(k\) 全部 \(-1\) 即可。
T3
好像没有那么难?
对于一个回文中心,其本来就有一个回文的部分 \(len_1\),后面又有一段通过循环可以相等的部分 \(len_2\),凯撒后后面还有一模一样的部分 \(len_3\)。发现答案是 \(len_1\) ,还是 \(len_1 + 2*(len_2-x)\),还是 \(len_1 + 2*(len_2 + len_3)\) 都是可以分讨加上线段树二维数点一类的东西直接判定的,可以直接做到 \(O(n\log n)\)。
Day 4
\(100 + 100 + 0\),\(\text{rk} 13\)。
T3 一个半小时憋出来 \(0\) 分。
T1
我有一个很牛的组合意义。
发现一个方案合法当且仅当每个点只有一个没有洞的儿子,称之为重儿子。
此时这棵树构成一堆链,每一条长为 \(L\) 的链的权值为 \(\dfrac{L*(L+1)}{2}\)。只要计数权值和的期望。
发现这正好是一条链的子链个数,因此直接对于每一条链统计他出现的概率并加起来即可。
设点 \(i\) 有 \(son_i\) 个儿子,则设 \(g_i = p^{son_i} + son_i * (1-p) * p^{son_i - 1}\),即该节点合法的概率,\(c_i = son_i * (1-p) * p^{son_i - 1}\),即钦定其重儿子后该节点合法的概率。
一条链的权值为恋上除了链底外的 \(c_i\) 之积乘上其他点的 \(g_i\) 之积。直接计算即可。
T2
直接选择点分治,找出每个点走到当前根的过程中血量的最小值 \(d_i\),到根时的血量 \(b_i\),从根走下来的过程中的最低血量 \(d2_i\)。那么一个点 \(j\) 可以被 \(i\) 走到当且仅当 \(-d_i \le t_i , -(b_i + d2_j) \le t_i\)。第一个是对 \(i\) 自己的限制,可以直接判掉,剩下一个式子,再加上他不能属于 \(i\) 所在的子树和要求的点 \(p\) 的子树,合起来就是个二维数点,可以离线直接计算。
T3
如果把每一个森林表示成一个序列,序列的第 \(i\) 位是 \(\lfloor \dfrac{iD}{h_x} \rfloor - \lfloor \dfrac{(i-1)D}{h_x} \rfloor\) 也就是第 \(i\) 天会砍多少树。
先不管这个东西长度很长,我们考虑一下经典(?)问题,有若干链,每次选一个点加入序列,链上必须按顺序选,最大化序列的前缀和之和。
这个东西放到树上也可以做,就是考虑那个最大的点,如果他可以选那么一定直接选,否则他父亲选了之后他一定下一个就选上。因此可以和父亲合并。放到序列上就是选出平均值最大的前缀加入最终序列。
放到图上理解发现只需要求出 \(y = \dfrac{D}{h_i} x\) 下的整点凸包,可以证明这只有 \(O(\log a_i)\) 个点。每次在 stern-brocot tree 上面二分出分子最大的 \(\le \dfrac{D}{h_i}\),并且分子 \(\le a_i - nowy\) 的分数。\(nowy\) 是凸包上一个点的纵坐标。
求答案并不需要类欧,因为都是整点,使用 pick 定理即可。
写了一天,但是代码很短。
有基于万能欧几里得或者连分数的高妙做法,我不会。
Day 5
\(0 + 0 + 0\),\(\text{rk} \infty\)。
什么也写不出来,写写题解吧。
T1
一个方法是直接维护动态重心,这据说可能会被卡常。
考虑一条边被经过的次数,发现就是他更小的那一边的子树,这是为了满足重心的性质。
没有修改的时候每个点的权值是一次函数,可以轻松维护两个子树什么时候谁更大。
带修改的时候发现子树和只有一条边受到了影响,直接暴力修改即可。
T2
设 \(f_{i,j}\) 为用 \(\le i\) 的边权使得 \(j\) 个点联通的概率,\(g_{i,j}\) 为用 \(\le i\) 的边连起来 \(j\) 个点但是不要求联通的概率。\(b_i = b_0 + \sum\limits_{j=i}^m b_j\) 有:
这里用到了钦定 \(1\) 所在的连通块大小的技巧。
发现这不足以统计边权为特定值的答案。如果要这么做的话只能把每个 DP 值设为一个多项式。
所以说可以考虑插值。把 \(0 \sim (n-1)(m-1) - 1\) 中的所有值都带进去算一遍,再拿出来插出多项式系数即可。
时间复杂度 \(O(n^3 m^2)\)。
T3
首先有直接贪心:每瓶药需要 \({\lceil \log_2k \rceil}\) 的时间,将药从大到小排序,答案就是 \(\max\limits_{i=1}^n{rk_i + \lceil\log_2{sz_i}\rceil}\)。最后一瓶比较特殊,加 \(rk_i - 1\) 即可。
但这样贪心是错误的,例子是 \(3,1\),拆成 \(2,1,1\) 更牛一些。
设上面贪心得到答案为 \(v\),我们可以证明答案 \(\ge v - 1\)。
设 \(s_i = rk_i + \lceil\log_2{sz_i}\rceil\),我们找到 \(sz_i\) 最大的 \(i\) 满足 \(s(i) \ge v\)。如果 \(s(i) > v\) 那就直接寄了。否则为了让答案变小,我们必须把他拆掉。设 \(x = 2^{\lfloor \log_2{sz_i} \rfloor}\),则我们只能把它拆成 \(x\) 和 \(sz_i - x\),如果拆的更小那么 \(sz_i - x > x\),就没有意义了。这也解释了 \(v-2\) 为什么是达不到的。如此这样下去,直到所有该拆的都拆完,就可以判断答案是否可以是 \(v - 1\) 了。
面对区间询问我们怎么维护呢?发现 \(\log\) 相同的只有最后一个是需要检查的,这个非常显然。我们只需要对后若干位排序然后 ST 表维护最小值即可。对后若干位排序可以模仿后缀数组,基数排序。
细节看起来非常多。
Day 6
\(100 + 25 + 48\),\(\text{rk} 16\)。纯唐分。
T1
发现每个点对答案的贡献实际上是独立的。
所以说如果我们要算答案 \(\le k\) 的的方案数,这就是一个反射容斥问题。如果一个点左儿子中有 \(L\) 个点,右儿子中有 \(R\) 个点。那么最终答案就可以乘上 \((0,0)\) 到 \((L,R)\) 的折线中不经过 \(y = x + k\) 和 \(y + k = x\) 的有多少,反射容斥解决,时间复杂度 \(O(\dfrac{n}{k})\)。
直接做复杂度是 \(O(n^2 \log n)\) 的,看似不能接受。但是我们发现其实对于每个节点,只有 \(k \in [\left|L - R\right|,\max(L,R)]\) 之间时,算出来的值才有意义(更大和 \(\max(L,R)\) 一样),区间长度其实是 \(\min(L,R)\)。众所周知轻儿子大小是 \(O(n \log n)\) 级别的。所以复杂度可以分析到 \(O(n\log^2 n)\)。
T2
先对 \(T\) 的正串反串建 AC 自动机,那么枚举 \(T\) 的断点,合法的 \(S\) 相当于一个在前缀的 \(fail\) 树子树里面,另一个在后缀的 \(fail\) 树子树里面。这是一个矩形,对于所有断点直接矩形面积并即可。时间复杂度 \(O(n\log n)\)。
有基于 \(\text{border}\) 理论的做法,但是我并不会。
T3
首先,任意两个开头位置不相同的子串的 LCP 长度 \(\le \log r\),于是比较两个子串的时间是 \(O(\log r)\) 的。
这个结论我没想到怎么证明,感觉只能分析到 \(2 \sim 3\) 倍 的 \(\log r\)。
先特判掉询问区间 \([l,r]\) 开头和结尾的 \(O(\log r)\) 个位置,使得询问区间的两端都落在整数的分隔处,设整数的范围是 \([L,R]\)。
假设现在选择了数字 \(z\) 的第 \(k\) 位作为开头。
- 如果 \(0 \dots k\) 这些位里有 \(0\),那么选择 \(z + 1\) 的第 \(k\) 位作为开头更优。
- 如果第 \(k + 1\) 位是 \(1\),那么选择 \(z\) 的第 \(k + 1\) 位作为开头更优。
于是 \(k\) 一定取 \(z\) 的极长的末尾 \(1\) 的个数。
所以,最优的 \(z\) 有三种情况:
- 全 \(1\)。
- 有一位是 \(0\)。(这种真的不被下一种包括吗?)
- 卡在了上界,即 \(z = r\) 或者 \(z\) 是最大的满足 \(z \equiv 2^k − 1 \pmod {2^{k+1}}\) 且 \(z \le r\) 的数。
并且,前两种情况只需要取最大的不卡上界的 \(z\) 即可,于是只有 \(O(\log r)\) 种情况。总时间复杂度是 \(O(T \log^2 r)\)。
Day 7
\(100 + 12 + 0\),\(\text{rk} 20\)。又是爆炸的一天。
T1
选择的点只有三种情况:
- 选一个叶子。
- 选两个有父子关系的点,分别割掉两个点连向父亲的边。
- 选两个不在同一个大子树(\(1\) 的儿子分出的子树)的点。
前两种直接计算。最后一种发现每一条非树边都会对他两个端点到根的链(树剖后)构成的 \(O(\log ^2 n)\) 的矩形构成贡献。直接扫描线,时间复杂度 \(O(n \log ^3n)\),加上 zkw 轻松跑过。
T2
从大到小加入物品。现在我们要保证任何时刻都没有人愤怒。
如果说 \(v(i,S_i) < v(i,S_j)\) 我们称 \(i\) 羡慕 \(j\)。此时新的物品不能分配给 \(j\),否则就会产生愤怒。
如果没有人羡慕 \(x\),则直接把新物品给 \(x\) 即可。否则羡慕关系一定形成一个环。随便找一个环,比如 \(r_1,r_2 \cdots r_n\)。那么令 \(S_{r_1} : = S_{r_2},\cdots S_{r_n} : = S_{r_1}\),则一定皆大欢喜,还消除了一个环。加入一个物品最多增加 \(n\) 条羡慕关系。所以消除的时间复杂度是 \(O(nm)\) 的。
T3
对于最终形态的矩形,如果一列/对角线是全黑的,那么我们就认为他被涂了。这样就不会算重。
考虑钦定一些列是黑的。那么其他列我们就认为他们都不是黑的。这样就相当于对于 \(n+m-1\) 条对角线我们有若干限制说对于一些长度为 \(n\) 的区间,这些区间中的数至少有一个 \(0\),对于没有被区间包含的位置则不算贡献。
如果区间确定了,那么我们只需要从左向右扫一遍,并记录末尾连续 \(1\) 的个数即可。同理我们设 \(f_{i,j}\) 为前 \(i\) 列,当前列末尾有连续 \(j\) 个 \(1\) 的方案数,可以直接转移到 \(k> i\) 列。只需保证 \(j< n\) 即可。复杂度 \(O(n^3)\)。
上面的东西是周神告诉我前两句话之后我二十分钟内胡出来的。可见我场上有多唐。还有爆标的 \(O(n^2)\) 以及 \(O(n)\) 做法,我可能会学习。
Day 8
\(80 + 0 + 8\),\(\text{rk}40\)。
T2写错文件名爆零了。
T1
通过打表发现(当然正解是直接计数),\(n\) 阶排列有 \(i!i^{n-i}\) 种使得冒泡排序 \(i\) 轮后排好,记为 \(c_i\)。
那么对于任意 \(i\),所有方案的逆序对数之和 \(d_i = c_i * \dfrac{i}{2} * (n - \dfrac{i+1}{2})\)。直接计算有复杂度 \(O(n\log n)\)。
瓶颈在计算 \(i^{n-i}\)。我们拆一下,\(i^n\) 可以欧拉筛直接算,在质数处暴力,时间复杂度 \(O(n)\)。设 \(i^i\) 为 \(ans_i\)。则对于合数 \(pq\)(\(p\) 为最小质因子),则 \(ans_{pq} = ans_p^q * ans_q^p\)。前面一项由于 \(p \le \sqrt n\) 可以直接预处理光速幂,后面一项考虑对于每一个 \(q\) 计算答案,由于素数间隔的结论,相邻两个素数 \(p_i\) 和 \(p_{i-1}\) 满足 \(p_i \le \dfrac{n}{q}\)。则 \(p_i - p_{i-1}\) 是 \(\ln \dfrac{n}{q}\) 级别的。因此暴力处理总时间复杂度为 \(\sum\limits_{i = 1}^n \ln \dfrac{n}{i} = O(n)\)。
我写了一个把每个数分成三个 \(\le \sqrt n\) 的东西,然后对于 \(\le \sqrt n\) 的数光速幂,对于 \(\ge \sqrt n\) 的素数暴力算贡献。这也是 \(O(n)\) 的,只不过常数太大过不了。
上面做法时间复杂度证明
要证明\(\sum\limits_{i = 1}^n \ln \dfrac{n}{i} = O(n)\),
也就是 \(\sum\limits_{i=1}^n \ln i = n\ln n +O(n)\)。
设上面这个东西为 \(f(n)\),那么有:
前后两个都是 \(n\ln n+ O(n)\) 的。因此原式就是 \(n\ln n+ O(n)\) 的。
T2
对于一条非树边,他必须大于他覆盖的树边。
那么对于一条非树边 \(i\) 和他覆盖的树边 \(j\),直接使 \(r_j = \min(r_j,r_i - 1)\),\(l_i = \max(l_i,l_j + 1)\),这是非常合理的。并且操作之后任意树边和非树边之间都满足 \(l_i > l_j ,r_i > r_j\)。这样我们在贪心匹配的时候是不会冲突的,前者一定逊于后者。
现在可以解决构造方案了。但是怎么要求最大字典序呢?
可以二分一个点的答案,只保留一段前缀跑 \(O(n\log n)\) 的暴力。时间复杂度 \(O(n^2 \log ^2n)\),据说能过。
有复杂度更牛的做法:判断一条边的答案时,先只保留其左端点跑答案,如果有解就继续,否则一定是轮到一个点时右端点小于当前下标了,直接将右端点左边的都标记为不合法,直接找第一个合法的就可以了。
时间复杂度 \(O(n^2 \log n)\) 或者 \(O(n^2)\),其实和 Hall 定理本质相同。
T3
好神秘啊,不写了。
四舍五入我把所有题都写完了!比起前面两轮算是进步了一点把。

浙公网安备 33010602011771号