当 OI 生涯只剩两个月的时候,你会做些什么?
鲜花
“我要勇敢地去把这一切拿回来” 『Mine (Illenium Remix)』
\(\boldsymbol{[2025/10/09]}\)
CF2150D
可以看成我们一次选择一个人,然后把和他相邻的两个人(若存在)吸过来和这个人合并。
先固定最后剩下的人数 \(k\)。最后只需要滑动这 \(k\) 个人的窗口即可。
除了两端的人以外,中间的人一定是由奇数个人变过来的。并且这个条件是 充要的。
然后枚举两端的奇偶性,然后全扣成偶数再 \(/2\)。
注意到每个位置期望的数是一致的,是方案数 \(/k\),然后 \(\times 2+1\) 还原一下。
接下来就是 \(\forall k\) 求 \(\sum\limits_{i=k}^n s[i-k+1,i]\),这个前缀和一下即可。乘上期望就是带权方案数。
注意两端的期望值要多加一些东西,并且区间要特判 只有一个元素 的时候,此时贡献为 \(n\sum a_i\)。
P14184
\(\boldsymbol{[2025/10/10]}\)
梦熊
T1 换根 dp 略。
T2 最初思路是对的,根据 \(2^{\cdots}\) 部分分,观察到几乎只和 \(\text{highbit}\) 最大的数的个数相关。
但是要对 \(len\le 4\) 的区间分讨,剩下的用你喜欢的数据结构维护。
T3 板子题,CF464E 多上一个减法就行了,麻烦一点。
T4 不会。。。
P3179
我们设每次选择一个白色的格子 \(i\),选择一个满足条件的 \(k\),翻转 \(S_{i,k}\) 集合内的格子,保证当前格子一定被翻转,且游戏能结束。
我们可以将游戏转化为每个格子有一个数,原游戏中白色初始是 \(1\),黑色初始为 \(0\)。
每次可以选择一个非 \(0\) 的数进行操作,当前数的值减一,\(S_{i,k}\) 的其他数加一。
游戏中,显然白色对应奇数,黑格对应偶数,我们只需要证明这个游戏与原游戏等价(必胜判定相同)。
设原游戏先手为必胜,显然可以按照原游戏策略进行,只翻转奇数,监督败方是否也只反转奇数,如果翻转偶数,将其变为奇数,则先手再次对那个格子进行翻转,可以证明奇偶性可以与后手操作前一样,使得后手在奇偶性上操作无效,重新变回自己。
而先手由于前提是必胜,所以总有奇数可以翻,\(0\) 是偶数,于是可以证明新游戏也是必胜方。
如果原先后手必胜,仿照上述,易证。所以等价。
结论就是可以分成 \(w\) 个子游戏,第 \(i\) 个子游戏只有 \(i\) 原来的白格是 \(1\) 其他都是 \(0\)。
而我们每次都是在一个子游戏上进行的,你可以能认为这仍然会互相影响。
但其实不是,这个序列现在实中表现为每个子游戏问题的序列对应的和,如果这个位置是 \(0\),则子游戏都为 \(0\),不能操作。
否则一定能看作一个子游戏进行的一次操作,因此可以分解。
于是我们得到了 \(SG(x) = \text{mex}\left(0, \mathop{\text{mex}}\limits_{k=2}^{x/2} \bigoplus\limits_{j=2}^{x} SG(j)\right)\),即 \(SG(x) = \text{mex}(0, SG(2x), SG(2x) \oplus SG(3x), SG(2x) \oplus SG(3x) \oplus SG(4x),\ldots)\)。
同时注意到 \(\dfrac{n}{x}=\dfrac{n}{y}\) 的 \(SG(x)=SG(y)\),因为它们递归的子问题是本质相同的,减少重复计算。于是类杜教筛分析有复杂度 \(\mathcal{O}(n^{3/4})\)。
\(\boldsymbol{[2025/10/11]}\)
AGC002F
一个方案合法当且仅当对于该方案的每一个前缀,白色球的个数 \(i\) 大于非白色的颜色种类数 \(j\)。
考虑在 \(n \times k\) 个位置上放球,设计状态 \(f_{i,j}\) 表示已经放入 \(i\) 个白球,\(j\) 种非白的颜色的所有球的合法方案数,可以通过加入一个白球或 加入一种颜色 来转移。为避免算重:
-
加入白球时,我们强制白球放入最靠左位置。
-
加入一种颜色是,我们强制该颜色的第一个球放在能使方案合法的最靠左的位置。
这样转移式子就可以很容易写出来了:
时间复杂度 \(\mathcal{O}(n^2)\)。
我觉得这题一整个颜色一起加入进去比较牛。
\(\boldsymbol{[2025/10/12]}\)
核桃
除了 T2 都是幽默题,纯纯来领工资的。
AGC006E
考虑这个操作每一列是相对固定的,只会 reverse 然后交换。
我们先判掉一些离谱的错误,然后问题就转化为:
给定一个 \(a_1, \dots, a_n\),保证 \(|a_1|, \dots, |a_n|\) 是一个 \(n\) 排列,保证 \(a_i, i\) 同奇偶。
每次操作将相邻的三个数 reverse 且均变成反数,问最终是否能变为 \(1, 2, \dots, n\)。
先做到 \(|a_i| = i\),只要所有 \(a_i \equiv i \pmod 2\),看交换同奇偶的相邻元素,一定可以构造。
只需要调整每个元素的符号使得 变成全正,我们发现可以按如下的方式操作:
1 2 3 4 5
-3 -2 -1 4 5 [1,3]
-3 -2 -5 -4 1 [3,5]
5 2 -3 -4 1 [1,3]
5 2 -1 -4 -3 [3,5]
1 -2 5 -4 -3 [1,3]
1 -2 3 -4 5 [3,5]
此时可以取距距离为 \(2\) 的两个点。
并且对于 \(a_1, a_n\),可以按下述操作先取 \(a_1 \sim a_4\) 再取 \(a_2, a_4\):
1 2 3 4
-3 -2 -1 4 [1,3]
-3 -4 1 2 [2,4]
-1 4 3 2 [1,3]
-1 -2 -3 -4 [2,4]
因此只要奇数下标和偶数下标中,符号错误的元素有偶数个即可。
发现交换 奇数 下标的相邻两个元素,会让 偶数 下标中符号错误的元素 \(\pm 1\) 个,偶数同理。
因此只要求出奇数下标和偶数下标子序列的逆序对奇偶性。
我们知道排列奇偶性 \(=(n - c) \bmod 2\),其中 \(c\) 是置换环数量。于是时间复杂度是高贵的线性!
AGC006C
根据期望的线性性,对称是线性操作,于是相当于每次 \(x_i\gets \dfrac{(2x_{i+1}-x_i)+(2x_{i-1}-x_i)}{2}=x_{i-1}+x_{i+1}-x_i.\)
根据 noip2021T3 方差 的经典套路,差分一下:\(d_i=x_i-x_{i-1}\),相当于每次交换 \((d_i,d_{i+1})\)。
此时问题转化为:给定一个排列 \(p\),求 \(p\) 复合 \(k\) 次后的排列。
此时直接倍增优化做到 \(\mathcal{O}(n\log k)\)。但是直接把每个置换环拎出来做即可 \(\mathcal{O}(n)\)。
AGC008D
考虑把 \(i\) 的分布拆成前 \(i\) 个 \(i\) 和后 \(n-i\) 个 \(i\)。然后对于两个部分分别贪心即可。
\(\boldsymbol{[2025/10/13]}\)
AGC011C
考虑 \((a,b)\) 和 \((c,d)\) 在一个连通块的条件。
观察新图上一条边的涵义:\((u,v) \leftrightarrow (p,q)\) 则说明原图有 \(u \to p\) 和 \(v \to q\),即有两个点能从 \(u,v\) 走到 \(p,q\)。
顺着这个思路,因为一个点可以来回走,所以 \((a,b)\) 与 \((c,d)\) 处于一个连通块表明原图存在 \(a\) 到 \(c\) 与 \(b\) 到 \(d\) 的简单路径,满足它们的长度相差偶数。
我们将图的连通块分为以下三种情况考虑:
-
含奇环的图。每个点到另一个点存在一奇一偶两条路径。
-
二分图。进行黑白染色,两种颜色之间的距离为奇数,同色点距离为偶数。
-
孤立点。它不与其他点连通。
设奇环、二分图、孤立点的数量是 \(a,b,c\)。
以下先不考虑孤立点。对于奇环奇环,奇环二分图,显然每一对都能贡献恰好一个连通块。于是其贡献是 \(a^2 + 2ab\)。
考虑左右部均有点的二分图,发现每一对二分图二分图能造成 \(2\) 的贡献,于是贡献是 \(2b^2\)。
最后算上孤立点的贡献。设 \(x\) 是孤立点,则 \(\forall y, (x,y)\) 与 \((y,x)\) 是孤立点,\((x,x)\) 也是孤立点。于是它的贡献是 \(c^2 + 2c(n-c)\)。
综上,\(ans=(a+b)^2+b^2+c^2+2c(n-c)\),总复杂度线性。
AGC001D
\(a\) 能随意重排非常关键!
考虑把 \(n\) 个数抽象为 \(n\) 个点,每个回文信息可以在对称的位置上连边,最后要求图联通。
\(n\) 个点的图联通至少要 \(n-1\) 条边。一个长度为 \(l\) 的回文串,可以贡献 \(\lfloor \frac{l}{2} \rfloor\) 条边。
因此,\(A \cup B\) 中最多有 \(2\) 个奇数。
可以构造了。很容易想到这种结构:

方便起见,使得所有交错的地方长度为 \(1\)。
分析发现,两头的线段长度奇偶性好像无所谓,但是中间的必须都是偶数。
那么把已知的 \(a\) 中元素的计数放到两头即可。特判 \(m=1\) 的情况。
AGC013C
考虑把碰撞的交换方向变成交换编号。相当于最后 \(n\) 个位置固定了,求每只蚂蚁对应哪个位置。
考虑若环是链,则所有相对位置不会发生变化,直接排序后一一对应即可。
对比链的情况:
考虑正着跨过 \(L\) 一次,带来了整体 \(+1\) 的循环位移;考虑负着跨过 \(L\) 一次,带来了整体 \(-1\) 的循环位移。
于是直接算这个位移值即可,复杂度线性!
\(\boldsymbol{[2025/10/14]}\)
P10627
\(\boldsymbol{[2025/10/16]}\)
CF1218D
仙人掌生成树等价于每个环断一条边,\(\text{xor}\) 边权就 FWT 一下,注意方案数模意义下可能是 \(0\),要特殊处理一下。
ARC207C
注意到长度最大的时候最后一个数一定最小。于是记录 \(g_i\) 表示 \([1,i]\) 能变成的最大长度,\(f_i\) 表示取得最大长度的时候,最后一个数的最小值。
我们现在要划分一个段 \([x, i]\),转移就是 \(f_i \leftarrow t_x, g_i \leftarrow g_{x-1} + 1\)。
考虑贪心找到这个 \(x\),显然是选择一个最大的转移点 \(x\) 满足 \(f_{x-1} \leq t_x\) 是最优的,因为 \(g_x\) 具有单调性,\(x\) 越大,\(g\) 越大,同时 \(t_x\) 越小,所以贪心是对的。
从小到大扫描 \(i\),设 \(t_j\) 表示 \(a_j \text{ or } a_{j+1}\text{ or }\cdots\text{ or }a_i\) 的值。这个可以每次将 \(j\) 从大到小枚举暴力更新直到 \(t_j\) 的值不变,那么此时比 \(j\) 更前的 \(t_j\) 显然也不会变了,因为一个数最多只能被更新 \(\log A\) 次,所以均摊下来暴力的复杂度是正确的。
\(x\) 可以在每次更新 \(t_j\) 时去更新。复杂度 \(\mathcal{O}(n \log A)\)。
\(\boldsymbol{[2025/10/17]}\)
AGC003F
初始图四联通很关键。
有了这个条件,我们就可以分三种情况讨论:
-
这个东西上下拼接、左右拼接都可以拼成一个联通块:显然答案是 \(1\)
-
这个东西上下拼接、左右拼接都不可以拼成一个联通块:显然答案是 \(c^{k-1}\),其中 \(c\) 为图中黑点个数。
-
这个东西上下拼接或者左右拼接 能拼成一个联通块(仅满足一个条件)
这里问题就稍稍复杂一些了。
首先发现两个问题是等价的,所以这里只讨论左右拼接联通的情况:
我们先观察样例一的二级分形图:(已经手动分块)

容易发现,联通块个数可以简单的表示为:原图的黑点个数 \(-\) 左右相邻两个都是黑格的对数。
然后我们把这个图当成原图,再放入一开始给出的图中,得到的新图的联通块个数也可以用上面这个表达式表示!
然后我们就发现,答案就是:\(k-1\) 级分形图中黑点的个数 \(-\) 左右相邻两个都是黑格的对数。
- 前者是好算的,答案为 \(c^{k-1}\)
如果我们设 \(a\) 为相邻黑点对数,\(b\) 为左右拼接边界相邻的黑点对数,\(c\) 为黑格数。
容易推出,左右相邻两个都是黑格的对数 可以写成矩阵连乘的形式:\(\begin{bmatrix} c & a \\ 0 & b \end{bmatrix}^{k-1}\)
然后写个矩阵快速幂就好了。复杂度 \(\mathcal{O}(nm+\log k)\)。
\(\boldsymbol{[2025/10/18]}\)
8:30 到学校睡觉 2h 后垂死病中惊坐起,发现:

嗯嗯来校直接不开灯,放完书包径直走到床边倒头就睡,学校的床在 死角!甚至前后躲过两个监控,隐藏真好,下次还敢。
奠定了一整天幽默奇异搞笑的基调。
梦熊
T1 太难蚌了,我猜了个每次删最大可删的,直接写了个线段树维护区间 \(\text{xor 1}\),删除一个位置,最大 \(0\) 位置。复杂度 \(1\log .\)
- 实际上找到最小的 \(a_x\equiv x\pmod 2\) 的位置 \(x\),然后每次删后缀极长的 \(100\cdots 0\) 段即可,数字的含义是 \((a_x-x)\bmod 2.\),复杂度是线性的。
T2 最开始没想到同余最短路,然后没想到同余最短路有更先进的 Alex_Wei 转圈,然后还被卡常,太幽默了。最终复杂度 \(\mathcal{O}(nV).\)
T3 赛前同学和我讨论这个怎么做,我几乎不假思索得,提出了牛子结论:答案形如 \(A^{k_1}B^{k_2}\cdots Z^{k_{26}}+S[*,r]\) 的牛子结论,我!竟!然!不!知!道!为!什!么!是!对!的!
- 因为我观察到,如果 \(k\) 很小,第一次一定是选前缀一段 \(A\)。但是后面猜的没有一点道理,真就纯纯狗运。
这个是今天最搞笑的一点,我自己设想的结论是假的,但是我表达出来的结论恰好是对的。
我设想的是 \(A\sim Z\) 遍历字符,分别扩展到不能再扩展,再把后缀选上。
于是我按我设想的写 WA 的彻彻底底,随便写了个暴力跑路了。
冷静思考发现:贪心是每次找到可扩展的最小字母,然后扩展。然后你发现,如果扩展完一段 \(A\) 后,隔了一会,再扩展到 \(A\) 时。
你第一次都没扩展它了,说明了这个 \(A\) 是走投无路被扩展到的,于是后面是选一段后缀。就瞎猫碰上死耗子证明了这个结论。
然后枚举字母,然后二分扩展。一次扩展还不一定能完全扩展,有可能 \(AAAB\) 扩展到一半,直接扩展后缀更优。要再判一下。
最后比较完 \(A\sim Z\) 后,还要比较两个区间的大小,就二分 lcp 或者 SA 即可。复杂度 \(\mathcal{O}(n|\Sigma|+q\log n|\Sigma|)\),写好一点可以通过。
T4 开出原题,是 P7841 改,我猜思路大致一样,没时间想了。
\(\boldsymbol{[2025/10/20]}\)
AGC012E
非常难蚌的题!
相当于 $\log $ 层每层选一段覆盖初始所有段。
- 注意到关键结论:初始只有 \(\log\) 段!否则一定无解。
然后每层的段处理出来,做个状压 dp,\(f_S,g_{S}\) 表示用了 \(S\) 内的所有层,最多扩展前/后缀多少元素。
最后枚举初始选了哪个段,判断一下即可。复杂度 $1\log $。
uoj 1004
牛子题啊!
我自己想到的是转 \(01\),枚举 \(i\) 分成 \(\le i\) 的 \(1\) 和 \(>i\) 的 \(0\),\(01\) 序列记作 \(a\)。
然后 \(U\) 相当于把序列中最前的 \(1\) 挪到最后,\(D\) 相当于把最后一个 \(1\) 挪到最前。
于是答案只和 \(U,D\) 的个数相关,枚举之。
然后之后我就不会了。其实之后的步骤不是特别难。
设有 \(c_U,c_D\) 个 \(U,D\),然后一个序列排好了,当且对于每个位置,要么左侧没 \(1\),要么右侧没 \(0\)(并且从位置来看这两个条件是独立的!)
于是排序的轮数可以被写为:
其中 \(L := \sum\limits_{k\le j} [a_k=0], R := \sum\limits_{k>j} [a_k=1]\) 分别表示分界线 \(i\) 左边 \(1\) 和右边 \(0\) 个数。
要求这个 \(01\) 序列中这种最小值最大值。我们可以发现 \(L_i, R_i\) 分别关于 \(i\) 单调递增和递减,所以这个值取在 \(L_i, R_i\) 相交的位置。我们维护之即可。
交点位置 \(i\) 减小和增大的总移动距离可以分别证明是 \(\mathcal{O}(n)\) 的(每个方向只会扫过每个元素一次),所以总移动距离是 \(\mathcal{O}(n)\)。
那么我们直接维护就是均摊 \(\mathcal{O}(n)\) 的。于是总复杂度 \(\mathcal{O}(nk)\),常数较大,需要减少除法卡常。
细节还非常多,要注意 \(/0\) 特化,以及 \(L,R\) 是 \(0\) 的时候,\(/0\) 就不需要特化。
uoj 949
神秘结论题。
观察比如一个人走的时候答案是 \(2(n-1)-\text{dia}.\)
比如当树高 \(\le k\) 的时候。考虑能少走啥,枚举最后停留的两个位置,相当于 \(2(n-1)-\) 路径长 \(\le k\) 的最长长度。
否则考虑所有树高 \(>k\) 的子树,其根都至少都被两个点经过,设其个数为 \(c\)。
相当于答案是 \(2(n-1)+2(c-1)-h-(h-k)\),其中 \(h\) 是树高。因为两个最多能分别少走 \(h,h-k\) 的路径。
uoj 950
非常难蚌的题,注意到位置 \(x\),+ 个数 \(c\) 的和始终是保持不变的!
由于最终一定到达 \(0,n+1\),所以最终 + 个数为 \((x+c)\bmod (n+1)\),然后卷积算一下即可,复杂度 \(1\log .\)
\(\boldsymbol{[2025/10/21]}\)
梦熊
T1 时光倒流并查集,骗骗没见过这个 trick 的人。
T2 对 \(a\) 根号分治,\(a\le B\) 是好做的。\(a>B\) 的先枚举 \(k\) ,同时记录每个 \(b\) 有多少个。
根据调和级数只有 \(n\log n\) 组询问需要枚举,每个询问由于 \(a>B\) 只要枚举 \(\dfrac{n}{B}\) 个 \(a_t\) 的倍数,然后判断一下有多少个 \(b\) 满足即可。理论能平衡到 \(\mathcal{O}(n\sqrt {n\log n}).\)
T3 原题是 qoj 9482,枚举是前面那个还是后面那个贡献,异或哈希。
然后比如扫描到 \(r\),维护一个栈,每次推入 \(i\),然后若栈顶元素出现两次,则弹出栈顶。
考虑所有 \([l,r]\) 的贡献,发现只能贡献到当前栈顶的那个元素。\(\mathcal{O}(1)\) 用哈希表算一下贡献即可。
用手写哈希表加上快读轻松卡到最优解。
T4 原题(极度卡常)是 gym104840D,题解,赛事写了难蚌 \(\mathcal{O}(n^{3.5})\) 卡时,理论最高 \(95\),挂了几个点变成 \(75\)。
P1971
根据奇偶性分析一定不能经过重复的点,于是转化成了二分图博弈板子题。
结论是:先手必胜 当且仅当 最大匹配一定包含起点。判定方法就是把起点删掉再匹配一次。
\(\boldsymbol{[2025/10/22]}\)
AGC014D
注意到若树有完美匹配则 后手必胜。
否则考虑叶子的父亲,先手染它,然后后手必须染这个叶子,否则下一步先手染了就赢了。
于是得出这个叶子的父亲必须只有这一个儿子,否则先手必胜。
然后就把这一对一起删了,递归下去,树依然没有最大匹配。就归纳证明了 后手必胜当且仅当树有完美匹配。
AGC011D
观察一下,发现:
考虑手玩一下 \(s = \text{AAAAA}\) 时是如何变化的:
| 步数 | \(s =\) |
|---|---|
| \(0\) | \(\text{AAAAA}\) |
| \(1\) | \(\text{BAAAA}\) |
| \(2\) | \(\text{BBBBA}\) |
| \(3\) | \(\text{AAABA}\) |
| \(4\) | \(\text{BAABA}\) |
| \(5\) | \(\text{BBABA}\) |
| \(6\) | \(\text{ABABA}\) |
| \(7\) | \(\text{BBABA}\) |
就是当首字母是 \(A\) 的时候,首字母变 \(B\)。
否则循环位移 \(1\) 位,在全局 \(\text{flip}\) 一下。
于是就可以 \(\mathcal{O}(k)\) 做了,具体就是记录循环位移了多少,\(\text{flip}\) 了多少即可。
注意到 \(A\to B\to \cdots\to A\) 后,后面一定形成了 ...BABA 状物。
于是在 \(>4n\) 步后形成 BBABABA... 类似的东西(看最后 \(5,6,7\) 步),会陷入两步一循环。
于是可以把 \(k\) 缩到 \(\mathcal{O}(n)\) 级别,就做完了。
\(\boldsymbol{[2025/10/24]}\)
露营
拉姆齐数论文构造题,题解
选拔赛
黄金分割代替三分法,题解
\(\boldsymbol{[2025/10/25]}\)
gym101237G
记 \(p_j\) 表示 \(\text{LCS}(s, t[i,j])=\text{LCS}(s, t[i,j-1])+1\),当且仅当 \(i\ge p_j\)。
考虑从 \(i=0\sim n-1\) 遍历 \(s_i\),去更新 \(p\) 数组。
for(int i=0;i<m;i++) p[i]=i+1;
for(int i=0;i<n;i++) for(int j=0,x=-1;j<m;j++)
if(s[i]==t[j]) swap(p[j],x);
else if(x>p[j]) swap(p[j],x);
这个比较厉害。做到了线性空间,复杂度 \(\mathcal{O}(n^2)\)。
\(\boldsymbol{[2025/10/26]}\)
P11152
把后缀的限制弄到前缀上,题解
\(\boldsymbol{[2025/10/27]}\)
P14303
二项式反演写 \(\text{EGF}\) 卷一下即可。
AGC015E
首先考虑三条线的情况。不妨设 \(x_1 \le x_2 \le x_3\)。发现如果 \(1, 3\) 有交点,那么 \(2\) 一定会贡献到他们。证明画图即可。
简单推广一下,先按照 \(x_i\) 排序。如果 \(i, j\) 有交点,那么 \((i, j)\) 的也对 \(i\) 有贡献。所以最后能把颜色传给 \(i\) 的点是个从第一个 \(v_j > v_i\) 的到最后一个 \(v_j < v_i\) 的区间。这样我们就得到 \(n\) 个区间,我们要求最后这 \(n\) 个区间中,每个区间中都至少有一个被染色的。
然后简单 dp,令 \(f_i\) 表示最后一个填了 \(i\),并且所有 \(r \le i\) 的区间 \([l, r]\) 都被满足。
令 \(mx_i = \max_{[l,r],r<i} l\)。容易得到 \(f_i = \sum\limits_{j=mx_i}^{i-1} f_j\),前缀和优化即可。
CF627D
\(\boldsymbol{[2025/10/28]}\)
工作
正常要写个线段树二分维护前 \(k\) 大,然后减的时候 \(=\) 最后一个数的要特殊处理。
但是由于只需要最终输出一次答案,于是直接二分出能被选的效率最小值,然后算一下答案即可。小常数 \(1\log\)。
P4811
直接粉兔 trick,枚举小的那边长度,再去掉重复询问,枚举量是单根号的。
然后枚举完 \(x\) 的一段,求出 \(y\) 在这一段的始末,判断相对位置是否发生变化即可。
但是这里要 lower_bound,带 \(\log\),理论离线询问能做到单根号。
在 \(y\) 区间长度小的时候扫描线,常数非常小,只比单根号慢一点。
CF848E
你这样吧,你先写一个 \(\text{poly}\) 的 dp 或者生成函数,然后求出 \(16\) 项递推式即可。
\(\boldsymbol{[2025/10/29]}\)
P10082
幽默整式递推。
\(\boldsymbol{[2025/10/30]}\)
P10106
\(\boldsymbol{[2025/10/31]}\)
P10074
由于知道的信息比较少,所以策略是比较单一的。
考虑 \(m = 1\) 的情况,两种极端策略是:
- 我抓住一个一直刀,直到死亡为止。
- 我刀死最小的小怪,如果某只小怪被刀了最小小怪血量次数刀没死,我就换下一只。
继续考虑 \(m = 1\) 的情况,容易发现我可以在最开始钦定一下我刀死小怪的血量,然后最坏情况下血量大于他的小怪都要被试错他的血量刀数。
仔细思考一下,发现 \(m > 1\) 也可以这么做,具体的,我们把 \(\{a_n\}\) 排序,考虑如果我们钦定了若干小怪 \(\{b_m\}\),最后死亡的是 \(a_{b_{1 \sim m}}\) 的时候我们最坏情况需要的代价。
不难发现根据之前的分析下标在 \((b_k, b_{k+1})\) 的小怪要被试错 \(a_{b_k}\) 刀,很容易依次设计状态:\(f(i, j)\) 表示当前考虑到 \(a_i\),确定了 \(b_{1 \sim j}\) 且 \(b_j = i\) 时最坏情况需要的代价。转移的时候枚举 \(b_{j-1}\) 转移,有:
相当于做 \(m\) 轮:\(f'(i) = \min\limits_{k<i}(f(k) + (i - k) \times a_k)\)。
这个式子不难用斜率优化,时间复杂度 \(\mathcal{O}(n^2)\)。
\(\boldsymbol{[2025/11/01]}\)
P14377
很厉害的搜索剪枝。
朴素想法是直接搜,预处理 \(\le 10^6\) 的结果,剩下的暴力搜,常数小可以过,跑的挺慢。
但是考虑对素数折半分组,变成 \(xy\le N\) 的最大 \(xy\)。
然后钦定一边 \(x\le \sqrt N\) 搜索,另一边搜到 \(x\) 的时候查询 \(\le \lfloor\frac{N}{x}\rfloor\) 的最大值。然后再交换再搜一遍。
但是每次 upper_bound 太慢了,我们发现大部分时候 \(x>10^{12}\),于是同样 \(\le 10^6\) 的数先处理处结果。这样跑得快一点。
- 注意分组的时候要隔一个取一个,而不是直接前后缀这样折半。加上上述所有优化跑得算飞快了。
\(\boldsymbol{[2025/11/03]}\)
ACM
vp Petrozavodsk Summer 2022. Day 7. HSE Koresha Contest,个人通过了 \(J,K\)。
B
写出 dp,线段树维护信息合并即可,复杂度 $1\log $。
F
幽默题。注意到只有 \(l=r\) 的区间比较确定,剩下的可以比较随意的决定。
按照 \(r\) 排序,依次钦定一个后缀 \(a_l=a_r\) 这样就行了。
J
总贡献减去桥能偷懒的贡献。
考虑两点之间走过的桥一定是形如上端点偏序下一个的下端点。显然需要分类 \(y_1<y_2\) 和 \(y_1>y_2\) 做两次。
现在考虑 \(y_1<y_2\)。首先注意到按照桥的起点(最下面那个)分类,只有 \(\mathcal{O}(n^2)\) 个本质不同的起点 \((x,y)\) 块。具体就是离散化一下。
考虑枚举终点桥,计算 \(x\ge a,y\ge b\) 的 \((x,y)\) 到终点桥 \(i\) 过程中经过最多的桥数量 \(f_{a,b,i}\)。
\(f_{a,b,i}\) 从 \(f_{a+1,b,i},f_{a,b+1,i}\) 和 \(a,b\) 桥的另一端点 \(f_{c,d,i}+1\) 转移而来。这个容易 \(\mathcal{O}(n^3)\) 完成。
然后枚举起点块 \((a,b)\),发现 \((a,b)\to (c,d)\) 经过 \(\ge t\) 的桥的所有方案,是 \(f_{a,b,i}=t\) 的所有 \(i\) 的终点 \((c,d)\) 所对应的 \([c,m]\times [d,m]\) 的矩形并,直接算贡献即可。
时空 \(\mathcal{O}(n^3)\),空间可能能优化到 \(\mathcal{O}(n^2)\)。
事实上思路是先想到 \(\mathcal{O}(n^2)\) 个起点块,再想到应该拆 \(=t\) 的贡献变成 \(\ge t\) 的贡献,然后再想到 dp。
K
太 tricky 的数学,先 CRT 拆模数。
对于 \(\bmod 255\) 随便做,现在考虑 \(\bmod 257\)。
相当于 \(ans=\prod\limits_{|S|=n/2} (a-2sum(S))^u\),其中 \(a\) 是所有数的和,\(sum(S)\) 表示 \(S\) 里数的和,\(u=\left\lfloor \frac{n}{2}\right\rfloor!\left\lceil \frac{n}{2}\right\rceil! \bmod 256\)。
当 \(n<12\) 时用你喜欢的暴力解决。
注意到当 \(n\ge 12\) 时 \(u=0\),答案只能是 \(0,1\)。
只需判定是否 \(ans=0\) 即可,即判定是否存在 \(|S|=n/2,sum(S)=\frac{a}{2}=x\)。
大胆猜一手 \(sum(S)\) 很容易覆盖 \(\bmod 257\) 的完系。
但是发现此时 \(n\) 充分大并不是一个条件,当只有一种数的时候觉坠机了。
但是联想调整法,考虑如果有 \(257\) 个非零调整值 \(d_0,\cdots,d_{256}\),那么其子集和一定覆盖 \(\bmod 256\) 完系。
于是当 \(n-\max c_i\ge 2\times 257\) 时,必定存在这样的调整,答案一定为 \(0\)。
否则对小的 \(c_i\) 暴力 bitset 优化 dp,然后枚举选了多少个小的即可。这里复杂度是 \(\mathcal{O}(\frac{p^3}{w})\) 的,其中 \(p=256\)。
\(\boldsymbol{[2025/11/04]}\)
P14312
严肃学习了二进制分组高维 KD-tree。
oi-wiki 中二进制分组写法比较厉害。
P10103
类似莫队求组合数前缀和那样,这题维护的是 \(n\) 错 \(m\) 的错排 \(F(n,m)\)。
不过要维护 \(F(n,m),F(n+1,m+1)\),然后回滚莫队。
\(\boldsymbol{[2025/11/05]}\)
P10105
首先把三个的中心点 \(p\) 设出来,并且解出 \(\text{dis}(p,u/v/w)=x/y/z\),不妨 \(x\ge y\ge z\)。
然后注意到中心点一定能在直径上取得!否则可以调整。
然后就是一个区间 \([x+1,\text{dia}-y],[y+1,\text{dia}-x]\) 取延伸下去的 \(\max\),看哪个能 \(\ge z\),再构造即可。
利用 ST 表,复杂度 \(\mathcal{O}(n\log n+q)\)。
P7275
已严肃 学习
loj 3995
判断一个排列是否可行,考虑将操作反过来:将排列的开头或末尾任意插入排列中。不难发现排列合法当且仅当存在一个长度 \(\ge n - k\) 的上升子区间,将该区间外的数依次向内插入即可。
令 \(m = n - k\),不妨计数所有极长上升子区间长度都 \(< m\) 的排列数量。
套用上述博客,\(F,G,H\) 分别表示任意,连续段合并,极长的 GF。
令 \(A(x)\) 为一个上升子区间的 EGF,即 \(A(x) = \sum_{i} [x^i]H(x) \cdot \frac{x^i}{i!}\),所求即为 \(n![x^n]\frac{1}{1 - A(x)}\)。
注意到 \(A(x)\) 只有 \(\mathcal{O}(\frac{n}{m})\) 项,所以直接暴力求逆也可做到 \(\mathcal{O}(n^2\log n)\)。
P10104
- 还是上述博客的容斥系数推导。
神仙容斥题!先考虑 \(m=0\) 怎么做。
首先容易加一个数差分一下,转化成 \(C=0\) 的问题。
然后考虑最早非全部顶到上界的位置,后面就有自由元了,就比较可以任选。
枚举这个最早自由位 \(d\),然后 \(f_{i,0/1,0/1}\) 表示前 \(i\) 个数,是否出现自由元,\(d\) 位上的值是 \(0/1\)。
复杂度 \(\mathcal{O}(n\log V)\)。
然后定义等价类为 \(b\) 的相等关系。转移是每次贡献一个极大独立集。
本身贡献系数 \([x^S]F=1\) 当且仅当 \(S\) 是独立集。等价类合并关系是 \(G(x)=\exp(x)-1\),于是容斥系数 \(H=\ln (F+1)\)。
然后这个 dp 也很神仙,把消除同类状态做到了极值。
考虑按 \(a\) 排序,每次钦定加入当前没选的最小的 \(a_i\)。
然后你发现 \(<i\) 的位你只关心它是否被当做最小的选了,\(\ge i\) 的位你只关心它选没选过。
于是状态数变成 \(2^n\) 了。枚举 \(i\) 枚举自己做 dp 转移,复杂度 \(\mathcal{O}(n3^n+n^22^n+n2^n\log V)\)。
\(\boldsymbol{[2025/11/06]}\)
ABC288H
加强到 \(N\le 10^6,M,X<2^{60}\)
求 \(f(x)=[y^X]\prod\limits_{w=0}^{M-1} \dfrac{1}{1-xy^w}\) 的 \([x^{0\sim N}]\)。
定义 \(L=61\),\(x\bullet y=\text{popcount}(x\text{ and } y)\bmod 2.\)
只需求 \(g_j=\sum\limits_{w=0}^{2^L-1} (1-2(X\bullet w))[c(w)=j]\)
接下来我们分布解决 \(g_j\) 和后面的多项式。
先考虑如何计算 \(c(w)=\sum\limits_{i=0}^{M-1} (w\bullet i).\)
把 \([0,M-1]\) 分成 \(L\) 段 \(i\in a+[0,2^b-1]\) 形式。设 \(w\) 的最低位为 \(lb\)。
-
若 \(b>lb\) 那么除了 \(lb\) 外的位置随便选,通过 \(lb\) 调整成 \(0/1\) 各一半,所以贡献是 \(2^{b-1}\)。
-
若 \(b\le lb\) 那么 \(w\bullet i\) 的有效值只取决于前 \(lb\) 位,显然有 \(w\bullet i=w\bullet M\),所以贡献是 \(2^b\) 或 \(0\)。
于是 \(c(w)\) 只和 \(lb\) 与 \(w\bullet M\) 相关,只有 \(2L\) 种取值。
但是还要考虑 \(w\bullet X\) 才能算 \(g\),不过随便 dp 求一下即可求出 \(g\)。
具体的,枚举 \(lb(w)\),记 \(f_{k,0/1,0/1}\) 表示确定 \(w\) 的 \(\ge k\) 的位,\(w\bullet M\) 与 \(w\bullet X\) 当前分别是多少即可。
- 注意别漏了 \(w=0\) 的情况。
如何求 \(F(x)=(1+x)^{-a}(1-x)^{-b}\),直接微分有限:
复杂度 \(\mathcal{O}(L^2+NL)\)。
ACM
vp Petrozavodsk Summer 2021. Day 7. MIPT Contest, GP of Dolgoprudny,只考虑非原题,个人通过了 \(I,J\)。
H
幽默诈骗题,注意到图是一棵树,加上 \(n\) 的因子这些孤立点。然后数据随机暴力跳即可。复杂度 \(\mathcal{O}(T\log n)\)。
I
直接 dp,\(f_{i,j}\) 表示 最后 \(i\) 步,经过至少一次 \(j\) 的概率。
每次转移就是 \(f_{i,j}\gets pf_{i-1,j}+(1-p)f_{i-1,j-a_{n-i}}\),注意每次 \(f_{i,n}\) 需要手动设为 \(1\)。
可以证明 \(a\) reverse 结果不变。
就是把路径根据时间翻转,再根据位置翻转,就得到了这个结论。
或者先考虑正数,相当于是一个前缀和的 \(\max\) 要 \(\ge x\) 的限制,才能走到 \(x\)。
而前缀和的 \(\max\) 这种有分配律的信息,就应该倒着推,做一个整体抬升这样的过程。然后直接这样维护也能过。
或者通过倒推想到上述做法也行。
J
牛子数论。先钦定 \((x_i,y_i)\) 互素。
由于是 \(\prod\),于是直接考虑素数 \(p\) 对一对 \((i,j)\) 的贡献。
首先算上 \(\text{lcm}(y_i,y_j)\),再考虑多算了什么除掉。
若 \(p\) 被多算了,首先 \(v_p(y_i)=v_p(y_j)\),否则分母就不可能是 \(p\) 的倍数。
否则 \(p^k\) 被多算了,当且仅当 \(\dfrac{x_i}{y_i}\equiv \dfrac{x_j}{y_j}\pmod {p^k}\)。
于是对于 \(v_p(y_i)=v_p(y_j)\) 的等价类,枚举 \(k\ge 1\),每当有一对 \((i,j,k):\dfrac{x_i}{y_i}\equiv \dfrac{x_j}{y_j}\pmod {p^k}\),就除一次 \(p\),累加起来自然是对的。
然后每个数把素因子算出来最后算贡献即可。懒得算复杂度了,反正肯定跑飞快。
\(\boldsymbol{[2025/11/07]}\)
走
朴素状压 dp 复杂度是 \(\mathcal{O}(2^n\times \text{poly}(n))\) 的。
考虑如何压缩状态,首先可以旋转整个环使得起点始终在 \(0\)。
然后对于从当前起点开始走始终走不到的点,我们都把它置为 \(1\)。
可以把环对称翻转一下,即每个位置 \(x\gets -x\)。
这样缩等价类后,可以证明状态是 \(\text{poly}(n)\) 的,实际 \(\le 10^5\) 个。
用 unsigned __int128 存储状态并且转移即可。
瓶颈在于哈希 __int128,目前代码至少能通过 \(n\le 127\)。
P14364
这题主要体现一个分阶段 dp 的思想,或者贡献延迟计算,有不同的理解。
相当于咔嚓 \(j\) 个的时候只关心 \(\le j\) 的被填了多少个,或者说 \(>j\) 的填了多少个。
等 \(j\to j+1\) 的时候枚举 \(j+1\) 填了多少个,再算贡献。
或者就是每个 \(j\) 相同的一段区间称为一个阶段。
\(f_{i,j,k}\) 前 \(i\) 个位置,咔嚓了 \(j\) 个,前面填的有 \(k\) 个(确定的)位置填了 \(\le j\) 的。
重新记 \(c\) 为 \(c_x=i\) 的 \(x\) 的个数,\(s\) 为 \(c\) 的前缀和。
枚举的 \(l\) 表示 \(>j\) 的中有多少个 \(=j+1\)。
复杂度 \(\mathcal{O}(n^3)\)。
\(\boldsymbol{[2025/11/09]}\)
P10441
经典结论:竞赛图三元环只和每个点的入度序列有关。
不难发现当入度序列为 $ [0, 1, ..., n - 1] $ 时没有三元环,当把一对 $ (x, x + 2) $ 调整为 $ (x + 1, x + 1) $ 时会多一个三元环。
直接调整复杂度是 $ \mathcal{O}(M) $ 的。可以考虑找一个最小的 $ n_0 \le n $ 使得其最大三元环量不小于 $ M $,在 $ n_0 $ 基础上调整,其余连成 DAG 即可。
-
最大三元环是在最平均的时候取到,当 \(n\) 偶数就是在一半 \(\dfrac{n}{2}\),一半 \(\dfrac{n}{2}-1\) 时取得。
-
可以证明每次把 \((x,x)\to (x-1,x+1)\) 最终一定能调整成 \(0,1,\cdots ,n-1\) 这个度数序列。
时间复杂度 $ \mathcal{O}(n^2) $,因为三方的差自然是平方级别。
\(\boldsymbol{[2025/11/10]}\)
ACM
打了 Moscow Pre-Finals Workshops 2019. Day 2. Grand Prix of China,个人通过 \(A,C,I\)。
A
注意到 \(a_x\) 一定替换成原序列中出现过的 \(a_y\)。并且 \(a_x,a_y\) 都是前缀第一次出现。
分讨 \(x<y,x>y\) 计算贡献,用你喜欢的数据结构维护即可。
C
很厉害的题,考虑第一次对半切,剩下每刀都要多两块,最后才能切成 \(n\) 块。
考虑每次左右剩余点的凸包,找到一条公切线,每次把公切线上这两个点切掉即可。
大概就是考虑 \(l\) 在凸包的下一个点,\(r\) 在凸包的下一个点,切的刀从两个线段之间穿过即可。
D
先考虑对连通的一棵基环树算一下 \(n\) 个点的基环树的方案数,以及环长和。(注意基环树可能退化成树,也要算进方案数里)
然后连通到不连通就用类似 \(\exp\) 的东西拼起来,这题直接展开 \(\exp\),系数是个组合数,同样记录方案数和环长和即可。
E
考虑怎么求 \(f(n)\),直接 dp 设 \(f_{i,j}\) 表示考虑前 \(i\) 位,和的绝对值是否可以为 \(j\),可以证明仅需考虑 \(j \le 9^2-1\) 的情况。
打表发现 \(f_i\) 作为 bitset 仅有不超过 \(2 \times 10^5\) 种情况,可以建出 DFA,在 \(n\) 之后加数位相当于 DFA 上走一步,最后走到的状态对应 \(f(n)\) 的值即为所求。
将 \(f(n)\) 的值作为类别,做 DFA 最小化后仅有 \(S = 715\) 种状态,剩下的部分就是数位 dp 了,时间复杂度 \(\mathcal{O}((S + T)d^2 \log R)\)。
G
给定正整数 \(p\) 和三元组序列 \(\{(a_k, b_k, c_k)\}_{k=0}^{\infty}\) 如下:
- \((a_0, b_0, c_0) = (2, 1, 0)\);
- \((a_{k+1}, b_{k+1}, c_{k+1}) = (a_k^2 + b_k^2, a_k b_k + b_k c_k, b_k^2 + c_k^2)\)。
\(n\) 次询问 \(x, y, z, m\) 表示求最小的 \(k \ge m\) 使得 \((a_k, b_k, c_k) = (x, y, z) \pmod p\),需判断无解。
\(n \le 5000, p \le 2^{30}, m \le 10^{18}\)。
solution
设 \(f_0 = 0, f_1 = 1, f_{k+2} = 2f_{k+1} + f_k\),则 \((a_k, b_k, c_k) = (f_{2^k+1}, f_{2^k}, f_{2^k-1})\)。
设模 \(p\) 意义下循环节为 \(L(p)\),类似 Pisano Period,当 \(p\) 为质数时,若 \((2 | p) = 1\) 即 \(p \equiv \pm 1 \pmod 8\) 则 \(L(p) | (p - 1)\),否则 \(L(p) | 2(p + 1)\);且 \(L(p^k) | p^{k-1}L(p)\),\(L(\prod p_i^{\alpha_i}) = \operatorname{lcm}\{L(p_i^{\alpha_i})\}\)。
先求 \(u\) 使得 \(f_{u-1} = z\) 且 \(f_u = y\),然后求 \(k\) 使得 \(2^k \equiv u \pmod{L(p)}\),两个 BSGS 即可,时间复杂度 \(\mathcal{O}(\sqrt{np})\)。
H
点分治把虚树拉出来 dp,复杂度根据实现优劣分别是 \(2\log\) 或 \(1\log\)。
I
幽默 burnside 加组合数算算算题,翻转同构真的一大坨屎。
J
优秀的拆分 + 萌萌哒 优化建图,跑最小生成树即可,纯纯数据结构堆砌。
\(\boldsymbol{[2025/11/11]}\)
P10707
假设输入的俩数为 \(N,M\)。设 \(M\) 的最高位 \(L=\lfloor \log_2(M+1)\rfloor\)。
定义 \((x)_k\) 表示 \(x\) 的二进制第 \(k\) 位。
定义凑出 \(M\) 的那些基底为 关键基。
我们先对关键基 dp,计算选 \(k\) 个关键基的方案 \(G_k\)。
再算出 \(F_{n,k}\) 表示 \(n\) 个数选出 \(k\) 个做关键基的方案。
那 \(ans=\sum F_{N,k}G_k.\)
\(f_{n,m}\) 表示从高到低考虑到第 \(n\) 位,选了 \(m\) 个关键基的方案数。
- 特判 \(m=0\) 的情况,转移是 \(f_{n,0}=[(M)_n=0]f_{n+1,0}\)
因为当 \((M)_n=1\) 时,可以加入一个最高位为 \(m\) 的新基底。
而对于 \((M)_n=0/1\),均可在之前选的 \(m\) 个中钦定奇数 / 偶数个这一位选 \(1\),方案数均为 \(2^{m-1}\)。
考虑设 \(g_i\) 表示大小为 \(i\) 的关键基能构成多少种序列。
朴素想法是在 \(i\) 个基的生成空间的 \(2^i\) 个数中,选取可重复的 \(N\) 个数,方案数为 \(\dbinom{2^i+N-1}{N}\)。
可是这样只能保证选出的数的基是 \(i\) 个基的 子集。还需要容斥一下。
转移是枚举 \(j\),表示选择一个大小为 \(j\) 的子基,然后减去他能构成的序列即可。
系数自然是 \(\text{q-analog}\)。
显然有 \(ans=\sum f_{0,k}g_k\)。此时复杂度 \(\mathcal{O}(NL+L^2)\)。
P7832
首先看成 bfs 分层,要求每一层依次是 \([1,a],[a+1,b],\cdots [z+1,n]\)。
朴素的 dp 是 \(f_{l,r}\) 表示当前考虑到 \([l,r]\) 区间,然后枚举上一个端点 \(l'\),判断合法性算贡献即可。
但是考虑对这判定条件 延迟计算。
比如有一条 \((u,v),u<v\) 的边,那么此时 \(u\le i\to j\le v\),则不能 \(i\to j\) 转移,发现这个显然是充要的。
于是 \(i\) 能转移到的只能是一个后缀 \([mx_i,n]\)。并且由于后面都没向前连边,代价是逐次 \(+1\) 的。
相当于 \(f_i\to f_{mx_i}\),之后 做一个 \(f_{i}\gets f_{i-1}+1\) 的转移。
然后 \(i\to mx_i\) 的代价相当于就是 \(mx_i-i-([i+1,mx_i]\text{ 中被前面连过的点的个数})\)。容易计算。
注意要在第一个被 \(f_i\to f_{mx_i}\) 转移的 \(mx_i\) 后才开始 \(f_{i}\gets f_{i-1}+1\),之前不能进行这项转移。
于是复杂度线性。
uoj 22
考虑依次 \(\bmod\) 的过程,我们实际只关心原序列的前缀最小值。
于是第一问就很好求了。把序列倒序排序,设 \(f_{i,j}\) 表示前 \(i\) 个数 能否 操作出 \(j\),\(f_{i-1,j}\to f_{i,j},f_{i,j\bmod a_i}\)。
注意最后答案范围只能在 \([0,a_n-1]\) 中找,因为 \(a_n\) 一定是一个前缀最小值。设第一问答案为 \(ans1\)。
然后类似插入法,记 \(g_{i,j}\) 表示考虑 \([i,n]\) 的数,从 \(i-1\) 传入 \(j\) 最终能操作出 \(ans1\) 的方案数。
转移就 \(g_{i,j}\gets (n-i)g_{i+1,j}+g_{i+1,j\bmod a_i}\),初值为 \(g_{n+1,ans1}=1\)。
第一个系数是可以插在任意一个比它小的数的后面,有 \(n-i\) 种方案,第二个系数是只能插在最前面。
复杂度 \(\mathcal{O}(nx)\)。
P8594
考虑形式太过简洁,对 \(n\) 设一个元 \(x\),对个数设一个元 \(y\),容易写出二元多项式:
具体就考虑放了几个竖着的,剩下横着的上下并起来,随便算一下就能得到。
但是考虑 \([x]\) 元初始是 \(\dfrac{\text{一次}}{\text{二次}}\) 的,并且次数始终不增,于是不用实际写二元 FFT,对于分子分母每个 \([x^k]\) 分别维护 \(y\) 的多项式手动算一下即可。
有现成的 二次剩余 Bostan–Mori 算法 可以抄,容易直接写出简洁的式子。
复杂度 \(\mathcal{O}(k\log k\log n)\)。
\(\boldsymbol{[2025/11/12]}\)
ACM
打了 Petrozavodsk Winter 2022. Day 6. ICPC Camp Day 1,我赛事通过了 \(A,B,C,G,H\)。
A
幽默题,爆标。考虑动态构建二分图,每个点加入左边还是右边取决于哪个能让中间的边更多。
这样构建了一共 \(N\) 个点,\(\ge KN\) 条边的二分图。
然后直接暴力拓扑排序那样依次删除度数 \(\le K\) 的点,可以证明最后左右必定剩下 \(\ge 1\) 个点。
B
我觉得是这一场最值得学习的题。
首先 \(m\) 关系不大,不难把 \(n+1\sim m\) 的概率缩到 \(n\) 的概率上。
合法情况的选 \(i\) 的期望数量 \(\times\) 合法情况概率,也可以看成所有合法情况【之于所有情况】选 \(i\) 的期望数量。
- 给出这题最关键的一步:考虑把每次递归 \(b_i\) 个,看成一个树形结构!最终从高到低就分别是 \([b_n,b_{n-1},\cdots ,b_1]\) 叉树。
然后发现多叉树每一层的所有节点其实都是等价的。于是我们不妨只关心一直向左走最后的叶子,求出合法情况下它选了每个 \(i\) 的概率。最后 \(\times \prod b_i\) 就是答案。
设 最底层是第一层,考虑记 \(g_{i,j}\) 表示考虑 \([i,n]\) 层,若 最左侧 \(i\) 层子树内抽卡最大值为 \(j\),最终 \(n\) 级抽卡 合法 的概率。
初始 \(g_{n,n}=1\),转移就是枚举除了最左侧外的最大值 \(k\ge j\),从 \(g_{i+1,k}\) 转移而来:
其中 \(s_{i,j}\) 表示 \(i\) 的剩下 \(b_{i+1}-1\) 个兄弟抽到最大值为 \(j\) 的概率。这里剩下子树就相对自由了。
记 \(f_{i,j}\) 表示 \(i\) 级合法抽卡(考虑 \(i\) 层子树)最大值 不超过 \(j\) 的概率,则 \(s_{i,j}=f_{i,j}^{b_{i+1}-1}-f_{i,j-1}^{b_{i+1}-1}.\)
\(f\) 的转移就是 \(f_{i,j}=f_{i-1,j}^{b_i}-f_{i-1,i-1}^{b_i}\),根据合法性只在 \(j\ge i\) 处有值。
\(g\) 的转移就前缀和优化一下即可。注意最后求的 \(g_{0,i}\) 要乘上选 \(a_i\) 的概率,因为我们之前只是假设了最大值是它,并没有乘上选择它的概率。
复杂度 \(\mathcal{O}(n^2)\)。
为什么一个从上到下,一个从下到上 dp 呢?
我的理解是 \(g\) 因为从下往上没法保证合法性,需要从上往下依次确定每个兄弟的合法性。
\(f\) 是子树限制,自然要从下往上 dp。
C
期望的线性性最关键。然后你就可以令 \(c_k\) 表示 \(k\) 美元期望能买通多少个人。
然后 dp \(f_{i,j}\) 表示 \(i\) 美元分成 \(j\) 份期望最多能买通多少人,转移就枚举 \(k\) 从 \(f_{i-k,j-1}+c_k\) 转移得到,此时 \(\mathcal{O}(n^3)\)。有两个思路优化:
-
首先可以看成做 \((\max,+)\) 卷积的 \(n\) 次幂,做个快速幂。
-
或者每次钦定转移最小的那份,此时 \(k\le \frac{i}{j}\)。
两者总复杂度均为 \(\mathcal{O}(n^2\log n)\)。
G
弱智,就是 XOR FWT 变换加加减减一下就行。
H
方案数显然是 \(\dbinom{n+m-1}{m-1}\),那乘积和怎么算呢?
可以生成函数得出答案是 \(\displaystyle {n+m \brace m}\),斯特林数单点容易 \(\mathcal{O}(n)\) 计算。
或者考虑枚举最后一个数,写出 \(f(n,m)\) 的递推,发现符合斯特林数递推。
J
考虑求 \(n\) 圆 \((x_i,y_i,r_i)\) 凸包面积。
相当于要求出两两圆的公切线,和所有圆弧围成的面积。
考虑凸集的支撑函数 \(h(\theta)=\max\limits_{i} h_i(\theta)\),其中 \(h_i(\theta)=x_i\cos \theta+ y_i\sin \theta +r_i\) 是每个圆的支撑函数。
几何意义是整个平面旋转 $\theta $ 角看最右侧点的 \(x\) 坐标是啥。
并且根据一些简单的数学计算,容易证明面积 \(S={\displaystyle\int}_0^{2\pi} h^2(\theta)-h'(\theta)^2\mathrm d\theta\),对 \(h_i\) 的最大值分段讨论一下即可。
复杂度 \(\mathcal{O}(n^2)\),可能能优化到 \(\mathcal{O}(n\log n)\),不是很懂。
\(\boldsymbol{[2025/11/13]}\)
P8392
考虑先贪心一个解 \(S\in [L-m,L+m]\):
先全部选上,若当前和 \(>L\) 就从 \(m\to 1\) 的物品一次删除并保证始终 \(>L\)。否则从 \(-m\to -1\) 依次删除。
此时方案是当前 \(S\) 的最优解,考虑调整到 \(L\)。
然后可以可以发现剩下的调整一定不会调整超过 \(m\) 个物品。也就是背包值域始终在 \([L-m^2,L+m^2]\) 中。
可以证明:若值域在 \([0,m]\) 的集合 \(A,B\),子集和 \(\ge m(m-1)\),则必定存在 \(A,B\) 的子集 \(S,T\) 子集和相等。
考虑若调整了绝对值 \(>m^2\) 的元素,把正负区分开,容易套用上面结论证明:存在子集和为 \(0\) 的子集。
那么此时把这一坨和为 \(0\) 的丢到初始方案中,就和我们原来假设矛盾了。
于是把加入 / 删除物品的增量放一起,做个多重背包即可。
单调队列优化,复杂度 \(\mathcal{O}(m^3)\),实测没有二进制优化的带 \(\log\) 跑得快。
\(\boldsymbol{[2025/11/14]}\)
CF67C
发现只有前三个操作是好做的,直接记 \(f_{i,j}\) 表示 \(A\) 的前 \(i\) 位和 \(B\) 的前 \(j\) 为匹配的最小代价。
- 插入:\(f_{i,j+1}\gets f_{i,j}+t_i\)
- 删除:\(f_{i+1,j}\gets f_{i,j}+t_d\)
- 替换:\(f_{i+1,j+1}\gets f_{i,j}+[A_{i+1}\neq B_{j+1}]t_r\)
考虑交换操作由于代价较大 \(2t_e\ge t_i+t_d\),我们可以分讨证明交换过后的字符 不会再进行任何操作,否则一定不优。
然后交换一定是找最近的能匹配的换过来。
设 \(p\) 为从 \(B_{j+2}\) 开始第一个等于 \(A_{i+1}\) 的位置, \(q\) 为从 \(A_{i+2}\) 开始第一个等于 \(B_{j+1}\) 的位置。我们交换 \(A_{i+1}\) 和 \(A_q\),使得它们分别匹配 \(B_{j+1}\) 和 \(B_p\)。
因为不会出现两次相邻的交换,所以最优操作序列形如删去 \(A_{i+2} \sim A_{q-1}\),交换,再插入 \(B_{j+2} \sim B_{p-1}\),这就引出了交换转移 \(f_{i,j} + t_e + (p - (j + 2))t_i + (q - (i + 2))t_d \to f_{q,p}\)。
\(p\) 和 \(q\) 都容易对每个位置预处理下一个等于某字符的位置快速得到。
复杂度 \(\mathcal{O}(n^2)\)。
树上水题
\(\boldsymbol{[2025/11/15]}\)
uoj 705
容易发现公差为 \(k\) 的等差数列可以写成 \(k^{-1}\) 个公差为 \(1\) 的等差数列的并。
证明就考虑 \(ak+b\) 把 \(a\) 拆成 \(pk^{-1}+r\) 然后取模考虑即可。
把 \(k\) 拆成 \(\frac{X}{Y}\) 其中 \(X,|Y|\in [1,\sqrt p]\),可以证明一定存在这样的拆法。
然后对于每个 \(X\) 单独处理询问,每个询问看成求 \(\frac{1}{Y}\times X\times (i+s\times X^{-1})\),其中 \(s=x+k-1\) 是起点,\(i\in [0,l-1]\)。
令 \(b_i=a_{iX}\) 然后做前缀和,对于 \(Y\) 查询这 \(Y\) 个连续段的和即可。复杂度单根号。
ACM
vp Petrozavodsk Summer 2020. Day 6. Korean Contest,本人场上通过 \(B,E,G,J,K\)。
B
神仙题。一种刻画二分图的新方式。
因为二分图是没有奇环的图,考虑用一种设置边权的方式,要求二分图异或和为 \(0\),否则不为 \(0\)。
考虑构造一个生成树,对于非树边定义权值 \(2^i\),并将树边异或上该权值,结论是这样处理之后的总边权异或和符合上述要求。证明考虑对于每条边的权值分偶环和奇环讨论,偶环异或偶环还是偶环,偶环权值和为 \(0\),奇环一定会有权值。
容易发现要割边一定不会割权值为 \(0\) 的边,所以求割两条边之后合法的数量等价于求 \(x \oplus y = 0\) 的边 \(x, y\) 数量。割一条边和不割边随便判一下就好了。
当然权值 \(2^i\) 显然做不到,其实直接 rand 一个整数即可。
E
当 \(n,m\) 均为奇数或 \(2k-1\ge \max(n,m)\) 时先手必胜,否则后手必胜。
F
还是考虑一整个连续段的转移。
定义代价 \(\text{cost}(l,r)=\text{cost}(l,r-1)+A_r\times C_{r-l+1}\)。
设 \(f_{i,j}\) 表示考虑前 \(i\) 个,有 \(j\) 个 没敲击 的键。
转移就空拍 \(f_{i,j}\to f_{i+1,j+1}\) 或者枚举连击长度 \(k\ge 1:f_{i,j}+\text{cost}(i+1,i+k)\to f_{i+k+1,j+1}\)。
\(+1\) 是因为连击后要空一个位置做断点。
答案就是 \(ans=\max\limits_{x\le m}f_{n+1,n+1-x}\)。目前 \(\mathcal{O}(n^3)\)。
发现 \(j\) 是每次递增 \(1\),对 \(j\) 逐层考虑。注意到第二个转移有决策单调性,优化到 \(\mathcal{O}(n^2\log n)\)。
决策单调性时,第一个转移不能一起考虑进去!否则就不满足决策单调性了!
G
SG 函数是 \(SG(x)=x-2\),全部异或起来判断是否为 \(0\) 即可。
J
一眼流子。
首先对于 \(k = 1\) 的情况,可以每个点拆点,入点向出点连 \(1\) 边,原图中的边连 \(+\inf\),实际上是求最小割。
考虑把问题看成 不能仅跳过 \(k-1\) 个点从 \(S\to T\),其中跳过是走一条割边。
对于 \(k > 1\) 的情况,考虑建 \(k\) 层图。
-
起点 \((0, S)\),终点 \((k, E)\)。
-
\((i,E)\to (k,E),w=+\inf,1\le i<k\)
-
本层就 \(u\) 入点 向 \(u\) 出点 连边,\(w=C_u\)。
-
每层 入点 向下一层对应的 出点 连 \(+\inf\),表示这个点被割掉了,不得不到下一层。
-
\((u,v)\) 就每层 \(u\) 出点 向 \(v\) 入点 连边,\(w=+\inf\)
可以发现如果一条路径有少于 \(k\) 个选择的点,那么就不是一个割了。
直接跑最小割,复杂度 \(\mathcal{O}(n^2k^2m)\)。跑飞快。
K
设 \(A\) 的特征多项式为 \(f\)。则 \(\det (A-xI)=(-1)^n f(x)\)。复杂度 \(\mathcal{O}(n^3+qn)\)。
\(\boldsymbol{[2025/11/16]}\)
ACM
Petrozavodsk Winter 2022. Day 2. KAIST Contest + KOI TST 2021。没工夫开了,漫做了一下,一堆论文题或者简单题没做,开摆了。
B
签到题,构造对角线,偶数的时候调整一下即可。
C
考虑枚举集合 \(S_1, S_2, S_3 \subseteq \{0, 1, \dots, N - 1\}\),要求 \(S_1 \cap S_2 = S_2 \cap S_3 = S_3 \cap S_1 = \varnothing\)。
于是要求
移项,有
令 \(F(S) = A(S \cup S_3) - A(S_1 \cup S \cup S_3)\),则我们要求存在 \(S\) 使得 \(F(S) < F(\varnothing)\)。
假设存在这样一个 \(S\),令 \(k = |S|\),定义 \(S_i\) 表示 \(S\) 的前 \(i\) 个元素构成的集合。
则我们一定能找到一个 \(i\) 使得 \(F(S_i) < F(S_{i-1})\) (否则 \(F(S) = F(S_k) \ge F(\varnothing)\)),也就是说
我们把 \(S_{i-1}\) 和 \(S_3\) 并起来,就证明了 \(S_2\) 只需要取大小为 \(1\) 的集合。
类似地,\(S_1\) 也只需要大小为 \(1\) 的集合。
暴力即可。时间复杂度 \(\mathcal{O}(N^2 2^N)\)。
E
区间图的一个连通块一定可以表为一个区间。
反过来,可以发现我们只需要将整个数轴划分为若干区间,在各区间中选择包含在其中的前 \(K\) 大个区间即可。不难发现这样一定可以计算出答案。
于是,要想将计算转移代价的过程优化到 \(\mathcal{O}(N^2 \log N)\) 或 \(\mathcal{O}(N^2)\) 是很容易的。
\(N^2\) 就维护只加数,维护前 \(K\) 大和。就拿一个指针维护选了哪段后缀即可。
K
直接考虑暴力:设 \(dp_{x,i,w}\) 表示在 \(x\) 子树内断掉 \(i\) 条边,且现在 \(x\) 所在的连通块的权值之和为 \(w\),是否可行。用树形背包容易得到一个 \(\mathcal{O}(nKR^2)\) 的做法。
注意到 \(i\) 固定时除了 \(x\) 所在的连通块以外的连通块的权值之和都在 \([L, R]\) 中,所以只有 \(R - L + 1\) 种,所以 \(w\) 只有 \(\mathcal{O}(K(R-L))\) 种取值。这样容易得到一个 \(\mathcal{O}(nK^3(R-L)^2)\) 的做法。
由于 \(dp\) 的取值只有 \(01\),所以显然可以用 bitset 维护,做到 \(\mathcal{O}(nK^3(R-L)^2/w)\)。
引理 1. 如果 \(dp_{x,i,w_1} = dp_{x,i,w_2} = dp_{x,i,w_3} = 1\),且 \(w_1 < w_2 < w_3\),且 \(w_3 - w_1 \le R - L\),那么将 \(dp_{x,i,w_2}\) 置为 \(0\) 也不会改变最终答案。
证明. 设 \(x\) 所在连通块最终的权值为 \(W\)。考虑如果使用了 \((x, i, w_2)\) 这个组合,那么把它换成 \((x, i, w_1)\) 或 \((x, i, w_3)\),则可以获得 \(W - (w_2 - w_1)\) 或 \(W + (w_3 - w_2)\)。由于 \(w_3 - w_1 \le R - L\),这两者也必然有至少一个是合法的,所以总是可以不考虑 \((x, i, w_2)\) 这个组合。
由引理 \(1\),在 \(w\) 的 \(\mathcal{O}(K(R-L))\) 种取值中,只需要保留 \(\mathcal{O}(K)\) 个为 \(1\) 的位置。所以复杂度为 \(\mathcal{O}(nK^3)\)。
\(\boldsymbol{[2025/11/17]}\)
ACM
打了 Petrozavodsk Summer 2021. Day 2. The American Contest,个人过了 \(A,C,I,J,K,M\)。
ARC209B
首先注意到要分讨绝对众数。
如果没有绝对众数,那么一定存在一种排列方式,使得没有相邻相同。
具体的,不妨设字母 \(a\) 是出现最多的数,那么把所有字母按
a..ab...b ... z...z的顺序排列成 \(S'\)。再把 \(S'\) 奇偶位拎出来,顺次拼接。此时一定满足条件。
如果有绝对众数,不妨设为 \(a\)。我们注意到其他字母没有本质不同,设为 \(b\)。
设 \(a,b\) 的个数为 \(A,B\)。考虑 \(a\) 插入 \(b\) 的 \(B+1\) 个空。
肯定先平均分,每份是 \(\lfloor \frac{A}{B+1}\rfloor\) 或者其 \(+1\)。
然后有偶数就比较麻烦,不妨调整 \(+1,-1\) 把两个偶数调成奇数。最后若还剩偶数就丢到开头或结尾。
这样每一段(除多出来的开头)连续的 \(a\) 都是奇数,也就不会和其他字母构成偶回文串。
并且这样调整不会使 \(a\) 的偶回文串长度增加。
于是就完成了构造。
ARC210E
动态维护每次加入 \(x\) 后的子集和,设为 \(S=\{a_1,a_2,\cdots,a_k\}\)。
令 \(r=1.01\),注意到若 \(y\le x<ry\) 则 \(y+a\le x+a< r(y+a)\)。
于是当 \(a_L\le a_{L+1}\le \cdots \le a_R<ra_L\) 时,不妨把 \(a_{L+1}\sim a_{R-1}\) 全部置为 \(a_L\),不影响答案。
复杂度 \(\mathcal{O}(n\log _r(\sum a_i))\),足以通过。
\(\boldsymbol{[2025/11/18]}\)
ARC169E
\(\texttt{R}\) 比 \(\texttt{B}\) 多一定无解,否则可以换成 \(\texttt{B}\texttt{B}\texttt{B}\texttt{B}...\texttt{R}\texttt{R}\texttt{R}\) 的形式,一定有解。
先找判断序列合法的充要条件。
考虑每轮的最优匹配策略是什么样的,我们希望更多的 \(\texttt{B}\) 能留到下一轮,因此要尽可能地让 \(\texttt{B}\) 和它后面的 \(\texttt{R}\) 配对。在多种配对方案能保留的 \(\texttt{B}\) 数量相同时,我们希望留下的 \(\texttt{B}\) 位置尽可能靠前,因为这样在下下轮它们被保留下来的概率更大。
因此我们得到这样的贪心策略:从左到右考虑每个 \(\texttt{B}\),将它和右边第一个未被配对的 \(\texttt{R}\) 配对。最终将所有剩下未被配对的数两两配对。根据上文可以知道这样做是最优的。
设 \(t_i\) 表示长度为 \(2^i\),且所有 \(\texttt{B}\) 尽可能靠右的合法解。
令 \(t_0 = \texttt{R}\)。
考虑怎么从 \(t_{i-1}\) 得到 \(t_i\)。从左到右处理 \(t_{i-1}\) 的每一位,若当前位是 \(\texttt{R}\),表示这位没被匹配,\(t_i = t_i + \texttt{R}\)(\(+\) 表示字符串拼接);当前位是 \(\texttt{B}\),我们希望下一个 \(\texttt{B}\) 尽量靠后,即与之匹配的 \(\texttt{R}\) 尽量更近,\(t_i = t_i + \texttt{B}\texttt{R}\)。不足 \(2^i\) 位用 \(\texttt{B}\) 补齐。
设 \(t_n\) 的第 \(j\) 个 \(\texttt{B}\) 的位置为 \(T_j\),原序列位置为 \(S_j\)。那么若存在 \(S_j > T_j\),则该序列不合法。证明大概是如果一个 \(S_j < T_j\),匹配数不会变多;但如果 \(S_j > T_j\),\(\texttt{B}\texttt{R}\) 的匹配数一定减少。
答案是令 \(S\) 满足上述条件的最小操作次数,即 \(\sum_{j=1}^{2^n} \max(0, T_j - S_j)\)。时间复杂度 \(\mathcal{O}(2^n)\)。
ARC138F
但是为啥按 \(x_1,y_1,\cdots, x_k,y_k\) 这样的顺序划分字典序呢?
因为考虑后面转移 \(j\to i\) 有个 \(g_j\subseteq g_i\) 的限制。具体看代码。
于是相当于对这些点按照 \(|g_i|\) 排序,就划分成这样了。其实没啥特殊的(笑
\(\boldsymbol{[2025/11/19]}\)
P14538
类似 NOI2024 D1T2 百万富翁,但是难度略简单。
注意到显然是做分治,有策略:
假设当前我们有一段长度为 \(n + 1\) 的序列 \(A\), 将其分为 \(L, R\) 两段, 这里面有 \(n\) 个数, 我们询问所有数是否在 \(L\) 中, 是的加入 \(X\) 集合, 否则加入 \(Y\) 集合。
有几种情况:
- 若 \(|X| < |L|\), 说明出现两次的数在 \(X\) 和 \(L\) 内, 递归做即可。
- 否则必然 \(|X| = |L|\), 这时我们询问所有在 \(X\) 内的数是否在 \(R\) 中, 如果是就说明答案就是这个数。
- 如果都不是, 那么说明出现两次的数在 \(Y\) 和 \(R\) 内, 递归做即可。
这样我们解决了问题, 但是我们如何保证操作次数呢?
如果我们记按上述方法解决大小为 \(n\) 的问题最优操作次数为 \(f(n)\), 那么有 \(f(n) = \min\limits_{1 \le x < n} \{\max\{n + f(x - 1), n + x + f(n - x)\}\}\), 其中 \(x\) 即 \(|L|\), \(\max\) 内分别对应上述三种情况。
由于 \(n = 99\) 不大, 写个 dp 找出来最优转移点即可, 可以得知操作次数最大值为 \(254 < 260\), 可以获得满分。
AGC035E
直接看这篇,这题要学的就是第一步不合法条件是有环,第二步平移一下然后逐层 dp。
\(\boldsymbol{[2025/11/20]}\)
P11922
并不需要记最大次大,每次钦定同色或者任意转移即可。
记录 \(a_j<a_i\) 的 \(f_j\) 最大值,以及此时 \(w_j=k\) 的 \(f_j\) 最大值即可转移。复杂度线性。
P11927
考虑把乘积分两半,阈值分治。
考虑枚举一条中间边,此时两边一定一边 \(\le B\),一边 \(\le V/B\)。
就是考虑前缀乘积最后一个 \(\le B\) 的位置,以及后缀积最后一个 \(\le V/B\) 的位置即可。
然后左边就搜 \(f_{i,x}\) 表示从 \(1\) 出发到 \(i\),乘积能否为 \(x\),注意处理边权为 \(1\) 的情况。
右边就比较麻烦,需要记录 \(g_{i,x}\) 表示从 \(i\) 出发到 \(n\),乘积为 \(x\) 的情况下左边最大能去到多大。
转移就类似最长路 dij 那样从大到小转移 \(\forall (u,v,w):g(u,x\times w)\gets \min(p_u,\lfloor \frac{g(v,x)}{w}\rfloor)\)。
右侧 dij 带 \(\log\),需要微调阈值平衡一下。复杂度大概是 \(\mathcal{O}(m\sqrt{V\log {(mV)}})\) 这类东西。
P11918
概率倒序排序,肯定是选前缀,看成 \([x^{\ge t}]\prod (p_ix+1-p_i)\),直接分治 FFT 做到 \(\mathcal{O}(n\log^2 n)\)。
以上是我糊的做法。官解是逆天屎,做一个 dp,注意到概率是一个类似二项分布,于是 \(f_{i,j}>\epsilon\) 的不会很多,维护之。
可以证明复杂度是 \(\mathcal{O}(n\sqrt {n\epsilon^{-1}})\),取 \(\epsilon =10^{-11}\) 足以通过。
P11606
先确定根,ban 掉所有 被钦定为孙子的点 和 被钦定不为祖先的点,剩下的点没有限制,事实上本质相同,任选一个做根即可。
考虑从根逐渐往下拓展连通块,直到拓展完整棵树。
确定剩下的点每个该挂在 当前连通块的 哪个点的 子树内,记录为 \(\text{bl}_i\)。
把 \(x,y\) 均还未填上的祖先关系的 \((x,y)\) 连通,记此时 \(u,v\) 连通性为 \(p(u,v)\)。
ban 掉祖先关系中祖先未被确定的孙子,ban 掉非祖先关系中 \(p(u,v)=0\) 的点,剩下点没有限制,任选一个 \(i\) 挂在 \(\text{bl}_i\) 上即可。
挂完记得更新 \(\text{bl}\) 数组,把 \(p(i,u)=1\) 的 \(u\) 的 \(\text{bl}_u\) 都变成 \(i\)。复杂度 \(\mathcal{O}(nm)\)。
P10367
对于每个连通块考虑,最后再乘起来。
-
若有奇环,则容易调整证明能达到所有 \(2^{n-1}\) 中方案,其中 \(n\) 是连通块点数。
-
否则考虑 偶数位取反 的 trick,等价于交换两个数,记取反后白点黑点个数为 \(x,y\),则答案为 \(\dbinom{x+y}{x}\)。
P11928
\(\boldsymbol{[2025/11/21]}\)
P10357
定义一组糖豆为每个颜色各一个的组合。则一个购买方案是一个组合的多重集。一个模 \(m\) 意义下价值为 \(x\) 的组合的最小花费 \(f_x\) 容易 DP 得到。有了 \(f_{1\sim m-1}\) 后跑一次同余最短路得到答案。
P6789
动态图
第一个修改连边,第二个修改 \(x\) 把第一个图 \(x\) 连通块缩成一个点,并在并查集里合并。
最后要么 \(u,v\) 连边过,要么 \(u,v\) 在同一个并查集,此时才是有边的。
- 注意并查集缩点后要把图的边也删掉。
憧憬
记 \(u\) 出点 \(v\) 的最小/大值为 \(a_u/b_u\)。则限制等价于 \(l\le a[l,r],b[l,r]\le r\),用你喜欢的数据结构维护,做到 \(1\log\)。
\(\boldsymbol{[2025/11/22]}\)
P9310
注意到答案 \(=\) 相交但不包含的线段对数 \(+n\),类似冒泡排序交换次数 \(=\) 逆序对数那样。用你喜欢的数据结构维护即可。
P9385
辅助数组交替转移 dp 的思想,题解
\(\boldsymbol{[2025/11/23]}\)
P11746
二维二项式反演,对于 \([2\mid x]\) 这样的条件用 \(\dfrac{1}{2}(1+(-1)^{x})\) 来刻画即可。剩下就是计算。
P9097
树状数组优化 dp 板子题。
P9100
水平恢复训练失败!做得破防,虽然不难但感觉至少水紫。
和 P5025,P11536 等诸多题都有联系,还是很不错的。
考虑相邻两个没被炸的转移,中间是一段都被炸的。钦定位置 \(0,n+1\) 没被炸。
相当于 \(f_l\to f_r\) 的条件是 \([l+1,r-1]\) 都炸了不会炸到 \(l,r\)。
对 \(r\) 满足不会炸到 \(r\) 的 \(l\) 是一段区间,\(l\) 同理。
\(l\) 差分一下,单点加单点删。\(r\) 做个树状数组区间和即可。
性质太薄弱没法优化到更优的线性,复杂度 \(\mathcal{O}(n\log n)\)。
\(\boldsymbol{[2025/11/24]}\)
CF1515E
连续段 dp 板子题,\(f_{i,j}\) 表示开 \(i\) 台,有 \(j\) 个连续段的方案数。
我们模糊段与段之间的间隔,只保证其 \(>1\),只关心相对顺序。
转移有 新建段,段扩增,段合并 共五种情况。
注意由于两段间的距离是不确定的,所以怎么插都是可以的,转移系数找份代码看。
猜测这个东西微分有限,挖个坑。
P7967
和上题一样连续段 dp。
ARC117E
稍微复杂一点的连续段 dp,考虑折线图从最上层往下 dp。
\(f_{i,j,k}\) 表示 \(i\) 层,\(j\) 对合法区间,\(k\) 个连续段的方案数。
P9252
直接把这三阶群同构到 \(\Z[3]\) 上,即红绿分别是 \(1,2\),合并是 \(\bmod 3\) 加法。
此时合法的必要条件是所有数加起来 \(\bmod 3\) 不为 \(0\)。
这个组合数算一下,可以线性预处理。
但是 \(1212\cdots 1\) 这样会造成矛盾,容易归纳证明只有 \(12\) 交替或 \(21\) 交替且长度为 \(>1\) 奇数时矛盾。
把这个扣掉即可。复杂度线性。
P11915
假设从大到小枚举 \(ans\),同时维护当前的每个连 \((u, v)\) 是否可行。
关键观察:对于一个 \(i\),连 \((u, v)\) 时,不妨设 \(\text{dis}(i, u) \le \text{dis}(i, v)\)。此时如果 \(\text{dis}(i, k) > ans\),从 \(i \to k\) 走的方法一定是 \(i \to u \to v \to k\)。
对于每个 \(i\) 分别做以下过程:对于 \(\text{dis}(i, k) > ans\) (即不合法的点),只需要对所有 \(i\) 维护 \(mx_{i,v}=\max\limits_{(i,k)\text{ has added}}(\text{dis}(v, k))\)。
然后把 \(\text{dis}(i, u) + mx_{i,v} > ans\) 的 \((u, v)\) 弹掉。当所有 \((u,v)\) 都被弹掉时是第一个 不合法 的位置。
时间复杂度 \(\mathcal{O}(n^3)\)。
P9108
朴素想法是 \(f_{i,[l,r]}\) 表示前 \(i\) 个,第 \(i\) 个选了 \([l,r]\) 的合法方案数。
转移前/后缀和优化容易做到 \(\mathcal{O}(nm^2)\)。
这样状态数就是错的,考虑直接记 \(f_{i,j}\) 表示前 \(i\) 个,第 \(i\) 个右端点为 \(j\) 的方案数。
枚举上一个右端点 \(k\)。
-
当 \(k\le j\) 时,\(f_{i-1,k}\) 对 \(f_{i,j}\) 的贡献为 \(kf_{i-1,k}\to f_{i,j}\),即第 \(i\) 个的左端点取在 \([1,k]\) 中才合法。
-
当 \(k>j\) 时,先把 \(jf_{i-1,k}\to f_{i,j}\) 贡献上,此时多贡献了两两不交的情况:\([j',j]<[k',k]\),需要扣掉。
此时不好对每个 \(k\) 考虑,对于 \(k>j\) 的所有 \(k\) 一起考虑。
不妨把数组 reverse 一下,即 \([K,K']<[m+1-j,J']\),此时 \(J\) 有 \(j\) 种选法,\([K',K]\) 的选法是 \(\sum\limits_{K<m+1-j}f_{i-1,K}=\sum\limits_{k>j} f_{i-1,m+1-k}\)。
于是我们得出转移方程 \(f_{i,j}=\sum\limits_{k\le j}kf_{i-1,k}+j\sum\limits_{k>j} (f_{i-1,k}-f_{i-1,m+1-k})\),前缀和优化做到 \(\mathcal{O}(nm)\)。
\(\boldsymbol{[2025/11/24]}\)
P6820
这题居然不能直接贪心。
dp 设计是容易的,\(f_{i,j}=f_{i-1,j-1}+1\),当 \(a_i=b_j\) 时,转移变为 \(f_{i,j}=\min(f_{i-1,j},f_{i,j-1})+1\)。
优化也是容易的,考虑枚举 \(i\),\(f_j\) 从 \(f'_j\) 转移。
转移分别为 \(f_j=f'_{j-1}+1\),\(f_j=\min(f'_{j},f'_{j-1})+1\)。
由于第一条占大多数,不妨记录 \(f_{i,i-j}\) 这样的东西,第一条就变为全局 \(+1\)。
第二条单独修改一下即可,复杂度线性。
P14383
发现一条线段放入一个栈后,和它相交的线段就只能放到另一个栈里,这就是二分图黑白染色模型。
将相交的线段连边,若不能染色则答案为 \(0\),否则记连通块数为 \(ct\),答案为 \(2^{ct}\)。
考虑对二分图先建 dfs 树,再判断是否为二分图。
建立 dfs 树的过程类似 P13842。
相当于维护删除一条线段,查询是否存在线段和一条线段相交。
用两颗线段树挂在一个端点维护另一端点的 \(\min/\max\) 即可。
判断是否二分图也一样线段树维护。复杂度 \(\mathcal{O}(n\log n)\),常数较大。
P9346
考虑恰好 \(i\) 步 \(f_i\) 变成 至少 \(i\) 步 \(g_i\),然后容斥:\(f_i=g_i-\sum\limits_{j<i}f_j\)。
接下来求 \(g\),即删掉 \(i\) 条边后每个连通块都是链的方案数。
这个直接 dp 就行了,\(f_{i,j,0/1/2}\) 表示 \(i\) 子树内删了 \(j\) 条边,\(i\) 当且度数为 \(0/1/2\) 的方案数。
树形背包转移,复杂度 \(\mathcal{O}(n^2)\)。
\(\boldsymbol{[2025/11/25]}\)
P5980
考虑先把体积拆成 \(1\)。然后考虑任意两杯温度为 \(T_1<T_2\) 的水,容易操作发现都能变成 \(T_1+x,T_2-x,x>0\),其中 \(T_1+x<T_2-x\)。
于是把相当于判断 \(k_i\) 个 \(a_i\) 形成的序列 \(A\),\(k_i\) 个 \(b_i\) 形成的序列 \(B\),是否有 \(A\succ B\)。
\(\succ\) 即优超,把 \(A,B\) 从大到小排序后,判断是否 \(\forall k,\sum \limits_{i=1}^k A_i\ge \sum \limits_{i=1}^k B_i\),并且 \(\sum A_i=\sum B_i\)。

浙公网安备 33010602011771号