2024FJ省队集训 - 笔记 & 游记
Day 0
火车上写了两道可爱小清新数学题。题没写多少bug还一堆。
我们住的是福建省团校,据说是福州有演唱会导致各种酒店房间紧张。
和 wzh,zzp 口胡了一些题目就去睡觉了。
团校的住宿条件确实不错,睡得挺香。
Day 1
T1
提交答案题就是依托美味的构式,你T2T3费劲心思骗个五分十五分还不如T1多草出两个点。
前三个点暴力或者手模都能过,赛时可以先算出这些问题的答案,顺便当作审题。
可以观察一些具有特殊条件的数据点,根据特殊性质写代码。
最后的一些大点可以使用爬山/退火算法得到较优解,卡一卡就能过了。
—— 出题人
原题是 P5225 [CTSC2018] 组合数问题
T2
广义进制线性基。
当所有 都为质数时,考虑从高位到低位插入,如果 有东西就消去 往下继续插入。
但是与普通线性基不同的是,你会发现 可以在最高位与自己消去,并且自己消去的结果非零。所以我们不能在看到 没东西时就结束,还要执行一步“自我消去”后往下继续插入。
当 时,假设 的当前位为 ,当前要消去的 ,则需要分类讨论:
- 若 ,则所有 能表示的数 都可以表示,直接消去即可。
- 若 ,则 能表示的数 不一定能表示,那么 是一个更优秀的基底,应当用 消去 后将 继续插入。
至于 无限制的情况,根据 Abel 群循环分解定理可以将 拆分为 的形式,然后根据前面的分析计算即可。
原题是 uoj#427 化学竞赛
T3
考虑 Subtask3,这一档部分分满足每次跳跃的步长较小。那考虑对于每种步长分别预处理前缀和,可以做到 。
接下来考虑根号分治。不妨假设起点为 ,假设跳了 步后可以到达 ,那么我们可以将 , 划分为 个小询问。显然这样答案是相等的。
那么如果我们能让 和 均小于 (注意绝对值),那么就可以沿用 Subtask3 做到单次询问 。
接下来我们发现每次总能找到一个满足条件的 和 ,于是就做完了。找 过程可以直接暴力跳,时间也是 的。
原题是 uoj#705 黄忠庆功宴
下午的题目讲解一大半都是科技题……
记录一些可能有用的Trick吧:
- 无穷大在模意义下等于 。
- 关于矩阵的有关问题可以考虑将矩阵进行初等行列变换使其变为对角线矩阵。
- 有若干(较少)返祖边的无向图的连通性问题可以将返祖边和连接的路径赋值 ,那么图的割就等价于你选出的所有边异或和为 。这里可能可以使用线性基优化。
晚上和大家讨论题目,吵了半天总算是把T3弄懂了,但是也因此错过了ABC的时间。
回到宿舍看了看ABC的题,感觉100min内AK稍微有点困难,但是题目相当无聊,幸好没打。
Day 2
T1
当字符集过大时可以使用主席树维护AC自动机,因为绝大部分转移边都是由 直接复制得到。
剩下的部分在AC自动机上跑最短路就行了。
T2
如果原图是一条链,则可以 找到两个端点,一次操作可以对两个元素进行比较,跑 nth_element 即可。
如果原图不是一条链,那么随即一条链后重心在链上的概率高达 ,所以扫一遍可以求出一个点左侧右侧的点的个数。
当然我们最后还要判断一个点是不是重心,这可以使用摩尔投票法。
T3
点分治求出路径,异或哈希判断答案。
有一车的corner case。
今天讲的是动态规划。
【NOI2023】 桂花树
考虑增量构造。
那么你可以进行以下三种操作:
- 在边上/点上接上一个点
- 在边上接上一个虚点 ,然后将 接在 上
- 将一个虚点填上 。
状压dp即可。
【JOISC 2017】长途巴士
考虑对 建立同余系。每一个缺水状态必须在一个循环内解决不然司机下车了。
先将所有人按照 排序。对每个人是否遗憾离场进行 dp。
表示前 个人的答案。
如果这个人不下车,那么他喝的水量是容易计算的。
如果这个人下车,那么他可能会带下来一个以他为右端点的区间的所有人。这一步可以使用斜率优化,转移时在凸壳上二分即可。
JOISC 2023】合唱
最优策略一定是第 个A和第 个B进行匹配,进而每次你会选出一个子串。
的限制可以使用wqs扔掉。令 表示前 个 A 被划分成若干段的方案数,那么有 。
这里就可以把 拆掉,一部分用单调队列,另一部分可以用斜率优化即可。
CF1608F
令 表示前 个数,,并且有 种数大于 的方案数。
考虑接下来确定这一位的值。转移是简单的。
【JOISC 2020】遗迹
和上一题一模一样。
考虑到如果一个柱子右侧有 的所有石柱,并且这个柱子的高度小于 ,那么它一定会被震塌。
所以考虑 表示后 个位置,最长连续到 ,转移与上题相似,注意对一个点最终是否消失分类讨论。
upd:实现时可能会需要考虑相同高度的柱子的去重问题,事实上这不重要:不管这回事,最后答案除以 即可。
【JOISC2022】错误拼写
考虑刻画字典序大小的判定: 中错位比较要么相同,要么第一次不一样需要满足偏序关系。
表示前 个字符最后一个为 的方案数。转移是容易的。
【JOISC 2023】JOI 国的节日 2
神题。
考虑正确的贪心方法:根据右端点递增排列贪心选取。
首先先用容斥转化为求假贪心和真贪心答案相同的方案数。记被真贪心选中的为红区间,假贪心选中的为蓝区间,都选中的为紫区间,都没选中的为黑区间。
先发掘性质:
- 按照右端点排序后,红蓝区间交替出现。(否则会违反原本的贪心策略)
- 相邻两个红区间的右端点之间不存在完整区间
- 所有区间的左端点都被包含在了一个蓝区间中
考虑 dp。每次插入一对红蓝区间,设 表示已经插入了 对区间,最后一个红区间的右端点前有 个未匹配的左端点,以及最后一次插入的是不是紫区间。
转移时要枚举上个红区间右端点到这个红区间右端点之间有多少个黑区间的右端点,然后统计贡献。时间复杂度为 。
考虑优化。你发现蓝区间对左端点有很强的限制,但是对右端点没有限制。这启发我们从后往前 dp。
具体地,设 表示从右往左考虑,已经有 个完整区间对,当前在最后一个红区间的右端点上,最后一个区间是不是紫区间的方案数。
转移时要枚举下一个红区间右端点在哪里,不妨设在 处。以 的转移为例:
那么你需要在这段区间内分配 个黑区间的左端点,上一组红蓝区间的左端点和下一组蓝区间的右端点。
先分配 个左端点。这暂时不会造成什么影响。
然后给上一组红区间分配一个左端点。加上首尾有 个可插入位置。
因为相邻蓝区间的右端点和左端点之间不能有其他区间的左端点,可以将它们当作同一个点处理。插入这个点的方案数是 ,因为我们前面已经加入了一个红色的左端点。
那你还需要给黑区间的左端点分配右端点,因为这两个相邻红区间右端点内不能有完整区间,所以右边有 个位置插入黑区间的右端点,方案数为 。
这样就完成了转移。时间复杂度 ,卡卡常能过。
【CTS 2019】氪金手游
弱弱弱弱化版:P4099 [HEOI2013] SAO
考虑如果原树是个外向树,那么答案只和子树中的 和有关,直接树形dp即可。
那如果不是外向树,那么考虑容斥,答案为总数减去反向数。
事实上我们并不在乎有哪些边被反向,我们只在乎反向边的个数,所以有 表示 子树中放了 个反向边,子树和为 的答案。
我们又发现 是不必要的,选择一条反向边等价于将dp乘上 ,所以可以做到 。
upd:大佬们称这种技巧为“上下边容斥”。
【CERC 2016】不可见的整数
其实可以直接 dp。
你发现我们会将一些提示相互连接来达到更短的长度。
考虑 表示当前已经出现了 ,左边是第 个提示,考虑到第 位;右边是第 个提示,考虑到第 位。
转移时考虑枚举下一个数字:你可能会增加长度,加入一个出现过的数字,或者更换你当前考虑的提示。
Day 3
- 今天出T1的人过于简单,直接找规律即可
- 今天写T2的我过于简单,想到了平方算法竟然不会推式子
- T3只有暴力的5pts,但是我忘记了交互题要加上
#include "soul.h"
,甚至在深思熟虑后将这行代码注释掉
T1
考虑差分数组,那么最后形成的一定是形如 ABACABA 的形式。
对每个长度为 的跳跃区间求前缀和即可。
T2
首先一个区间可以被删干净,当且仅当其众数的出现次数小于区间长度的一半。
于是我们可以枚举区间长度,再枚举非众数的数的个数,得到
注意到形如 的形式可以对 进行递推,所以我们可以暴力求出 的答案,那么每次乘上一个系数就可以求出第二层循环的值了。
T3
- 交互题一定要记得特殊的头文件引用
先进行 次询问,那么我们可以知道 个形如 “ 相邻” 的限制,将这些限制连边我们可以得到若干个环。
环的操作不是十分容易,考虑将环在某一点断开,不妨设链头为 和 。
随便挑两个位置询问,则分为以下四种情况,每种情况概率相等:
- 答案为 ,则四个位置的值全部确定。
- 答案为 或 ,则可以知道两个位置的值,剩下是一个大小减一的环。
- 答案为 ,则会留下一条单独的边。
至于最后的一组单边可以在期望两次内求出,这样总操作次数是 的。
下午主要讲了计数题
【THUPC 2024 决赛 L】 连向未来
注意到你可以把你的方案分割成若干不可分割的小段,而每一段的答案只和段长有关,所以可以写成一个多项式 。
分割小段的总方案数就是 。所以你现在需要求一个多项式的逆的某一项的系数。
拆开后可以将多项式转化为递推关系,可以用矩阵快速幂优化。
【CCPC Final 2023 B】Periodic Sequence
令答案为 ,考虑前缀最小值序列 。
显然根据最优性序列长度一定为 ,并且 一定是 的一个前缀,中间的数都是 接上它的若干个前缀。
所以所有 可以对应一个 的拆分,要求第一个数大于等于后面的所有数。
这是答案的一个上界,并且令 可以达到这个上界。
考虑计算每个 的贡献,也就是固定第一段的长度为 ,用长度不超过 的数字使得其和为 的答案。
考虑枚举第一段长度 ,那么有递推式:,这可以用生成函数刻画为 ,忽略常数项的误差可以得到
所以答案的生成函数为 。
当 时暴力,使用多项式求逆能做到 。
当 时,可以将分母展开,得到 的形式,也就可以做了。
鬼知道能不能卡过去。
优美匹配
- 给定一张 个点无重边无自环的图,求是否存在一个匹配使得权值和为 的倍数,。
Paffian求匹配是什么东西,求教qwq
- 这玩意在竞赛方面的用处极小,暂时先跳过吧
FJOI2020 D2T2
- 求凸多边形的 边形划分方案数
划分的对偶图是一棵树,问题转化为 个点无标号无根 叉树计数。
考虑对树进行 dfs 的过程:遇到空子树往上走一步,遇到新节点往右走一步,转化为格路计数问题,你不能碰到直线 。
传一张讲课的图:
这个翻转操作真的很妙,它巧妙地化解了由先前翻折操作带来的斜率错位问题,并且沿用了容斥的思路。
CF814E
考虑根据BFS序分层图,那么每层都是一段区间,层内可以连边,每个点到上一层有且仅有一条边。
设去掉到上一层的边,还有 个一度, 个二度,层内有 条边,那么到下一层还有 条出边,每个出边随便对应一个点,方案数为 。
内部点的方案系数可以容斥解决。
认为二度点是两个点,考虑钦定 个重边, 个自环,那么选取了 个二度点,算一下容斥系数即可。
考虑dp。记 表示当前考虑了 个点,往下一层有 条边的方案数,那么 。
考虑枚举 ,分步转移:
时间复杂度 。
排列
- 将长度为 的数组分为 段,每段长为偶数
- 将 的随机排列填入,然后将偶数位置上的数升序排序
- 定义一个划分的价值为排列中每段逆序对数乘积的期望,求所有划分的价值和。
- 组询问,
首先乘积有一个经典组合意义:每段内取红蓝两数,使得红蓝满足逆序对关系。
dp式子自己手推似乎有bug,先鸽着。
最长上升区间
- 给定长度为 的数组,每一位有取值 ,求每一种可能的数组中最长上升区间的长度和。
考虑拆贡献,转化为对于每个 求出所有长度为 的区间均不上升的方案数。
“不上升”的条件不好做,考虑容斥,答案等于选择若干个长度为 的上升区间的带容斥系数和。
有相交的上升段又可以合并,所以只需要求出 上升的方案书以及用长度为 的区间有交集地覆盖 的带容斥系数和。
第一问考虑对所有 预处理答案: 表示 的方案数,那么 ,这部分可以使用多项式科技优化。这里我们只需要求出 的值即可。
第二问有递推式 ,最后再一步递推就能求出答案了。
【ucup stage 10 Zhejiang K】Power Divisions
-
有长度为 的数组 ,对每个 都要求满足二进制下第 位为 的 的所有 之和为 。
-
求 的最大值。
-
闻起来像背包。如果每个变量的取值范围不大那么直接dp即可。
所以这题有一个很神仙的 Trick:通过数位dp来缩小变量的值域,按位确定变量的值
令 表示填了 位后背包剩余为 的答案,那么你在这一位上最多产生 的贡献,这样 都小于等于 ,剩下暴力转移即可。
-
在整理题目时翻到了 @Alex_Wei 爆切此题的记录。
-
又一次被吊打.jpg
【ABC288Ex】 A nameless counting problem
。
Day 4
- 考得最好的一天。
T1
先将计数转期望,看到距离和考虑拆贡献,那么每条边的经过次数就是它左右两侧人数的乘积,乘上边权即为答案。
注意到一条边只有操作的那一次可能会导致左右两侧乘积不同,所以考虑求出每次操作对答案影响的期望。
具体地,假设左侧有 个人,右侧有 个人, 上本来有 个人, 上有 个人,那么定向 对答案的变化就是 。发现 和 与之前的操作无关,根据期望的线性性,只要能够维护出每个时刻的 和 即可快速求出答案。
考虑一次定向操作: 可能会变成 或者 ,二者概率相等。所以 ,。
然后你又发现 和 相互独立,所以交叉项完全可以拆开为 ,所以这题就做完了。
T2
考虑枚举端点在 中的出现位置,那么合法的前后缀在失配树上均对应一条到根的链。
所以对正反串建立失配树,那么这样转化成一个数据结构问题:给定若干组 ,若 在 子树中, 在 子树中,那么 就会对答案有贡献。
考虑在 上跑dfs,那么满足条件的 就是 子树内所有标记在 上的链并。这一部分使用线段树合并即可做到 或者 。
T3
- 考场上没时间了
考虑wjq分块。
将每 行划分成一个块,那么每个矩形最多对两个块造成影响,并且都会和块的上/下边界存在交点。
那么对于每个块,将和它有交点的所有矩形拎出来,对于每个矩形,在左端点处打上与它高度有关的标记,在每个端点查询距离 的标记的最大值即可。
这样划分后整个大矩形将被划分成 块,连边后跑并查集即可。
下午讲的是图论专题,内容大多都在魏老师的博客里有所涉及。
挑一些有趣的题来记一下吧。
【AGC056C】 01 Balanced
区间问题可以用前缀和刻画。那么我们可以得到 ,以及根据值域要求有 。
事实上你直接跑差分约束就能得到字典序最小的解。证明考虑最短路树,每个元素都取到了其最小的可能值。
但是直接跑会出现负权边,用SPFA硬上肯定是不行的,考虑优化建图。
,考虑还愿 ,这样就有 ,以及天然限制
- 显然在最优解里不会出现 的情况。因为 的最优解对应着 的最优解,而 的最优解一定是满足题意的。
然后这是一个 01bfs 的形式,直接跑差分约束即可,时间复杂度线性。
【POI2010】 MOS-Bridges
首先“最大值最小”先套一层二分,假设当前得到的限制为 。
解决存在无向边的欧拉回路问题等价于判断是否存在一种将无向边定向的方案使得新图存在欧拉回路。
根据这些限制跑一遍最大流即可。
【CF1458D】 Flip and Reverse
考虑 是减一, 是加一,那么一次操作等价于将一段路径镜像翻转。
考虑记录当前的 坐标,那么一段区间对应着一段路径,那么一次操作等价于将这段路径反着走一遍。
所以建出图来等价于求出字典序最小的欧拉回路,贪心即可。
【ARC161E】 Not Dyed by Majority (Cubic Graph)
首先如何判定一个颜色序列是否无解呢?如果一个点最终颜色是白色,那么如果这个点连向了一个黑色点,那么剩下两个出边必须都是白色点。这是一个 2-SAT 问题,只需要判断无解即可。
构造题的一个新Trick:如果答案在样本空间的占比比较大,那么可以随一个答案然后判断是否合法。
这题你随一个答案满足题意的概率高于 ,所以多随几次就能得到一组答案了。
sto Alex_Wei orz
Day 5
马马虎虎。这把至少没挂分,但是我应该考更高的。
T1
一次函数的二阶差分为零,你发现字符串哈希可以非常好地刻画它,于是秒了。
- 数据水得一批,差评
T2
- 先写了个凸包,发现 的选取有顺序,于是这题先跳过开T3去了。
首先这题你只要把所有 塞到一个凸包里去就好了。所以问题在于怎么求这个凸包。
像这种“对于所有 ”的问题可以考虑进行分治,处理两侧的答案后进行合并。
合并的过程是个闵可夫斯基和,所以有 ,所以最终凸包大小只有 。
剩下的在凸包上二分答案即可。注意对正负数分类讨论一下
- 判定能草过 ,差评。
T3
一眼 LGV 引理,拆一下式子得到
暴力枚举排列之后右边的部分是 P8863,这样能拿 50pts。
但是还不够。根据 LGV 引理的过程,我们不难想到:如果能将 函数拆成与 有关的若干什么东西的乘积,那么就可以使用行列式进行优化。
既然 P8863 的思路已经走到了尽头,我们考虑直接使用组合意义暴力计算:你发现如果去掉“每次拿走两个不同位置”之后的问题是相当容易的。
接下来令 ,
考虑容斥。设钦定 个时刻放上相同的东西,并且每个位置被同时选择 次,那么你需要计算这么一个式子:
考虑将组合数拆开,没用的东西放到前面去,那么右半边式子就是
记 ,总体写出来就是
交换求和号之后得到:
将 塞到 里去,那么右边就是一个行列式的形式:
- 注意接下来的 定义与上文略有不同。
注意到你只需要求出 个位置的系数,所以你只需要带入 个点值到多项式里,求出行列式的值之反推系数,带入计算即可。
sto hhoppitree orz
今天下午讲了乱搞题的杂题选讲。
高级随机数 mt19937
:
#include<random>
using namespace std;
mt19937 rnd(time(0));
mt19937_64 rnd_ll(time(0));
signed main()
{
printf("%d %lld\n",rnd(),rnd_ll());
}
-
图的割和环可以考虑随机映射+异或哈希刻画。
-
只要算法的准确率 ,那么经过 次运行就可以达到高准确率 。
【FJOI2015】 最小覆盖双圆问题
首先你要会最小圆覆盖问题:随机打乱序列,每次增加一个新点 去更新答案:先从 找到一个最远点 ,以 中点为圆心做出新圆 ,然后找到一个 在 外,则 三点的外接圆就是答案。
那两个圆怎么办呢?你发现总能找到一条直线分割两个点集,答案为两个点集的最小圆覆盖的最大值。
那么每次我们随即一条直线,多随几次就能求出答案了。
- 随机化套随机化,不愧是 FJOI !
【PKUSC2022】 Colorful Tree(弱化版)
-
给定一颗 个点的树,边上有颜色。一条路径合法当且仅当路径上的颜色只在这条路径上出现。
-
求最长的合法路径。
考虑给每条边赋一个随机权值,然后对每个颜色随机选出一条边赋值为其他相同颜色边的权值异或和。
那么一条路径满足条件当且仅当它的路径权值异或和为 ,记录到根路径异或和作为点权,那么等价于两点点权相同。
剩下的部分随便跑个DSU on tree 即可。
【BJOI2014】 想法
你看这个计分方式就不像是正常确定性算法能过去的对吧。
-
有一些随机化题目会出现一些较为宽松的条件,看到这些不同寻常之处就可以考虑随机化的可行性。
-
Lamma:在 中随机选取 个数,最小值的期望为
考虑给所有入度为 的点赋一个随机权值,每个点记录能到达它的最小权值,多随个几次就能得到答案了。
【NOI2022】 挑战NPC
判断树同构考虑使用树哈希。
先对 和 分别跑一次树哈希,因为 足够小,所以可以先将哈希值相同的子树配对,那么一个节点最多剩下 个子树。
暴力枚举排列向下递归即可。
【NOI2019】 斗主地
每个位置初始时是个一次/二次函数。所以我们大胆猜想操作结束后每个位置仍然可以用一个一次/二次函数表示。
二次函数只需要三个数就可以确定,所以记录第一个、第二个和最后一个位置的期望值,暴力转移即可。
【FJOI2021】 外星飞碟问题
-
给你一个数列
-
输入 ,求 ,对一个大数 取模。
-
注意到答案为 。
为什么呢?我证不出来。
Day 6
- 不给大样例真当FJOI打是吧……
- T1 考场上写了一个抽象东西,对拍挂了半小时,最后被内存制裁。你应该写一个离散化的。
- T2 暴力写挂了
- T3 写了暴力,但是出题人数据太水,拿了25pts。
T1
事实上如果每次能找到与原先矩形有交集的矩形,那么暴力扩展的事件复杂度就是对的。
所以你现在需要快速有效地找到和某个新矩形有交的矩形。
考虑在 轴上建立线段树,那么我访问到当前 区间后已经保证了如果这个区间内存在矩形,那么在横坐标上一定有交点。
所以我们现在只要判断在纵坐标上是否有交点即可。
首先你直接扫一遍这个区间内所有的矩形会似。
注意到插入的顺序可以自己决定,所以我们可以对矩形的下底边排序,这样我们就保证了每次插入时的下底边一定是比原先的所有矩形都高的。
每次查询矩形时就可以用一个类似于当前弧优化的玩意快速找到能够合并的矩形,尽可能合并之后返回即可。
合并可以用并查集维护,于是就做完了。
原题 luogu P5998
- 注意空间问题。值域是 ,但是 只有 ,需要离散化。(我就是这样挂分的wwww
T2
构式题。就比 AT_arc158_e 多了一点点东西而已
套路分治。但是你发现 有可能从分支区间内跑出去,但是你又发现如果敢跑出去那么一定是走一个 形状,这部分可以预处理得到。
注意到最短路径最多跨过分治中心一次,所以考虑左右两点 ,记 为 到分治中心从上往下第 个点的最短路,对 同理。
套路地把 拆开:不妨假设 是最小的,那么要满足 ,移项可得
这是一个二维偏序,可以扫描线+树状数组维护。
为了防止重复计算,不等号是否可以取等需要多加斟酌。
T3
这不是高联原题吗
——@yizcdl2357
忽略强制加的情况,那么每次体力归零后,都会先加一次,然后加减轮流进行。
记 表示第 次归零的时间,那么 ,,解得
所以归零的时间数量只有 级别。我们只要求出 夹在哪两个归零时间内就可以求出 时刻的体力值。
那如果有钦定怎么做呢?你发现操作 次后就会再次落入循环,所以此时我么有一个 的暴力。
首先如果一个位置本来就是加,那你强制这个位置加法是没用的。
那如果将一个原本的减改成加,那么对答案几乎没有影响。
- 事实上除了加减段的最后一个位置,最终剩余的体力值是一样的。即
-+-
变成了+--
所以你要询问的位置个数本质上只有 种。总时间复杂度为
下午讲了数据结构。难度中等偏上,重点是题目种蕴藏的Trick。
【JOISC2022】 鱼 2
考虑判断 能否幸存:区间内只让 吃,判断能不能吃掉所有的鱼。显然每次先往左吃到尽头再往右吃走一个折返跑的路线是最优的。
接下来你会发现一个事情:如果某条鱼可以越过它吃不掉的鱼,那么它的大小至少翻倍。
所以如果你将所有能吃到相同左端点的鱼放到一个等价类里面,那么最多只有 个等价类。
考虑将鱼放到线段树上去。每个节点存储能吃到左端点和右端点的所有鱼。合并区间直接暴力扩展等价类即可。
时间复杂度两只log。
【JOISC2022】 监狱
首先因为每个人只能走最短路径,所以一定存在某个顺序使得每个人要么不走,只要一开始移动一定不能在终点前停下。
那我们可以得到以下限制:
- 若 A 的起点在 B 的路径上,那么 A 一定先于 B 出发。
- 若 A 的终点在 B 的路径上,那么 A 一定后于 B 出发。
倍增优化建图,最后跑一遍拓扑排序即可。
【UNR#4】 己酸集合
- 二维平面上有 个点
- 组询问,每次问以 为圆心, 为半径的圆里面有几个点
直接写方程得到
所以令 ,那么有
先对 排序,那么你要考虑 在 上的截距 的直线个数。
那么有一个暴力:动态维护 的顺序,那么最多交换 次,最后一次二分即可得到答案,时间复杂度为
你现在手上有一个更暴力的做法:对于每个询问直接枚举所有 ,时间复杂度是 。
当你发现时间复杂度含有 高次+低次 的形式时,可以考虑分块/根号分治,我们将直线每 个分一块,变化次数是 的;对每个询问求出每块内的答案,询问次数为 的。
令 ,则总时间复杂度为 。
【北大集训2021】 魔塔OL
- 新Trick:用bitset维护高维偏序
首先如果已知怪物集合是简单的:先按 从小往大打 的,再按 从大往小打 的。
加上时间维,能打的怪物是一个四维偏序。CDQ肯定是废了,考虑 bitset,bitset块长为 。
将怪物按照贪心顺序排序,赋值新的编号。
对每个维度分别排序,维护该维度上大于等于 的所有 的集合 。那么能转移 的所有点就是 的并集。
在每一块内暴力枚举所有可能情况对应的答案,那么每个块取并集后可以做到 合并答案。这一点类似于四毛子算法。
总时间复杂度为 ,取 ,则时间复杂度为
【北大集训 2021】 简单数据结构
简单你个锤头。
你会发现取min和 这两个操作对单调性都不会有影响,但是原序列不具有单调性,这让我们很难受。
所以考虑建立两颗线段树,第一颗线段树最开始是初始序列,第二颗初始为空。那么如果只有区间加i可以直接用懒标记解决。
那全局取min呢?我们发现:假如一个数第一次被成功地被取min操作了一次,那么你可以认为这个数本来是inf。
所以我们第二课线段树就派上用场了:如果一个数在第一个线段树里被取了min,那么就把它扔到第二课线段树中。所以第二课线段树存储的非空位置是单调不降的。
单调的限制意味着在第二课线段树上,取min相当于后缀赋值。稍微维护以下即可。
同时每个元素只会从第一颗线段树被拉到第二颗线段树一次,所以总时间复杂度为 。
upd:额这题最好是这样就写完了。
你还需要考虑一个重要问题:一个节点什么时候会被拉到第二颗线段树里?
考虑整体二分。设我们二分到了 ,则我们要对于所有元素,找到 的最小值,判断它是否大于零。直接建凸包即可。
【Ynoi2016】 掉进兔子洞
注意到答案等于三个区间总长度减去同时出现在三个区间内的数字的个数。
但是这里的“个数”和“种数”需要加以区分。具体地,我们在离散化的过程中要预留下相同数字的位置,每次加入元素时从第一个该元素对应的位置开始找到第一个为 的空位置即可。这部分可以使用bitset优化
剩下套一个莫队就好了。但是lxl卡空间,所以你还需要将询问拆分成若干段分别做。
【北大集训2021】 小明的树
约定点亮是白点,没点亮是黑点,那么条件转化为只有一个黑色连通块,并且根节点为黑色。整棵树都是白色的情况特判就好了。
Trick:树上联通块的个数=点数-边数,所以判定可以采用数个数的方式简单计算。
剩下的用一个线段树维护每个时刻的连通块个数和权值和就好了。
【ZJOI2016】 大森林
一颗树只会“生长”节点,所以如果我们只知道一棵树最终的形态也是可以处理询问的。
常见套路,离线下来对序列扫描线,维护最终每棵树的答案。
你发现你需要支持将一个子树移动到另一个节点下面,这可以用LCT完成。
注意到wjq不会写LCT。摆。
【JOISC2020 扫除】
- 加入和删除只要有一个好处理,你就可以用线段树分治。
在这题中,删除是容易的:只要忽略这个点就好
所以我们不妨一开始就假设这些点存在,然后把它们都删掉,最后用线段树分治撤销删除。
那么现在所有点都是已知的。然后你发现如果将所有被推过的点拎出来,那么他们的横坐标递增,纵坐标递减。
仿照 P8987 的思路开两颗平衡树维护所有点,如果一个点第一次被操作到就将它从第一颗平衡树扔到第二颗里面,简单维护即可。
【UR19】 前进四
- 长度为 的序列, 次操作
- 需要支持单点修改,询问一段后缀的不同后缀最小值个数
楼房重建线段树是两只log的,会被卡爆。
为什么呢?因为你发现每次询问的都是一个后缀,而维护线段树时我们可以求出所有区间的后缀最小值个数,在这里造成了浪费。
考虑从后往前扫描序列,维护时间维。那么每次相当于区间取min,答案为更新值的次数。用一个 Segment Beats(吉司机线段树)即可做到单log。
【FJWC2017】 comparison
-
递归定义集合间大小比较,这里的每个集合 包括两个集合 ,初始定义两个集合 和 , 是最小的集合, 是最大的集合,
-
当且仅当
-
当且仅当:
-
次操作, 表示 , 表示
-
第 次操作产生一个新集合,编号为 ,由已经存在的两个集合组成,问有多少集合教育等于
-
-
足够逆天。当时讲课时dalao们一眼后缀平衡树,给wjq看傻了。
首先所有集合满足全序关系,所以我们可以给每个集合赋一个权值,那么比较两个集合只要比较它们的权值。
将新集合和原集合的比较可以做到 ,所以可以用一颗能够维护大小关系的平衡树来维护每个节点的权值,显然你可以将节点权值赋值为 ,然后假如新集合插入在 中间就对应 。
甚至为了这题特地学习了后缀平衡树。哈哈
Day 7
收官之战,但是打的不是很好。
T1
wjq发现了一个线性做法,但是他在 512Mib 的内存下开了 6 个长度为 1e7 的 longlong 数组,100分 挂成 0分。
首先小于 的质数 必然对应 ,所以对于每个数我们只需要记录它最大的质因子就好了。
假设有 个质因子出现了 次,那么答案就是 。
考虑当 时会发生什么事情:会有一些质因子突然大于了 ,需要被排除;同时 会对答案产生贡献,需要再次维护 的值和最终答案。
这样就是线性。卡卡空间就能过
T2
首先根据单调性, 把题目转化为对每个值 求出能使最大子段和 的最小操作次数。
设原序列为 ,最终序列为 , 的前缀和为 ,那么根据题意有 ,移项可得 ,并且
换元 ,那么可以再次化简为 。答案即为 的最小值减去所有 之和。
接下来我们把这个图建出来。那么你会发现 向 连了一条长度为 的边(以下称为红色边),同时任意两点之间都有一条长度为 的连边(以下称为黑色边)。
那么 的答案其实就是对应着一条 的最长路径。又因为都是从小到大连边,所以你必然会一段黑色一段红色交替行走。
不妨假设最开始都是红色边,此时答案减去所有 之和刚好是 。那么如果你现在想要走一段 的黑色边,就相当于让答案增加 。
所以这等价于选出 个不相交区间,答案为 减去选出区间内所有 的和。在不同的 中选出最大的那个就是答案。
所以当我们枚举 之后就是 P6821 的套路,可以用线段树维护。
虽然我们不能枚举 ,但是 的范围只有 ,而每个 选出的区间和也是知道的,所以你现在要求出若干 在 处的最大值,对于 求和。
所有直线构成了一个凸包,剩下的在凸包上推个式子就好了。
T3
一般图最大权匹配,但是边权等于连接的两点的点权之和。
本题有一个贪心引理:
- 每次选择一个权值最大的点仍到一个集合内,若存在一个匹配包含这个集合,那么一定存在一个最优方案包含该集合。
我们将所有数按照 分成大数和小数,那么大数之间一定不能匹配,根据引理将大数作为左部点按顺序跑一个匈牙利就可以得到哪些大数一定不在最优匹配里。
那我们希望剩下的小数尽可能互相匹配。
考虑计算出每个类型的“最大匹配数”,就能得到每个类型最小剩了多少个。
那么如果所有类型的最小剩余量都不超过总剩余量的一半,那么可以两两匹配,最后根据 的奇偶性可能会剩下一个没有匹配的。
否则,一定会存在一个类型超过一半。现在我们只剩下了wan型的所有小数,暴力模拟即可。
下午讲的题目分享就不写了,真的没听懂qwq
听完题目分享吃个晚饭就上车了,福厦高铁真的很快(赞)。
写在最后
这趟省队集训题目质量很高,讲课很有趣。
唯一的遗憾就是那些写挂了/没写出来的非常可做题吧。每场比赛事实上有两道以上的题我都是会做的,但是真正能打满两道的只有一次(暴力还写挂了)
还有可能自己的代码速度还是不够快,也见识到了dalao们的实力,我和他们的差距还是很大的。
菜就多练。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?