NOIP
11/4 Day 1
A
题解:题读错浪费 2h。注意到其实题目给定了每个点的所有出边的编号可能。这也就是说只要我们从叶子节点开始,由于叶子节点的度数为 \(1\) 则那条边一定会确定。那么我们如果从叶子开始往上转移,每个点到它儿子的边都确定后只剩下它到父亲的边也一定能确定。这样我们就确定了所有的边。
确定后我们判断是否相同的边都构成简单路径,一条简单路径只会有两个点度数为 \(1\),其余所有点度数都为 \(2\),以这个条件判断即可。
我以为只有某些点确定了出边导致贼难实现。
B
题解:我们先假定 \(n>m\),如果一开始不是就转一下然后 0/1 取反。
先考虑没有 \(\texttt ?\) 的情况,答案就是 有 0 的列的数量 和 有 1 的行的数量 取最大值。
考虑设计 dp,\(f_{i,j}\) 表示考虑了前 \(i\) 列,有 \(j\) 列选了至少一个 \(\texttt 0\) 的方案数。发现性质,若 \(f_{m,j},j<m\) 则至少有一列全都是 \(\texttt 1\),也就说贡献为 \(\max(j,n)\);若 \(j=m\) 则说明每一列都有一个 \(\texttt 0\),贡献为 \(m\) 依然 =\(max(j,n)\)。这样我们就得到了一个 \(O(m^2)\) 的 dp。
我们发现对于 \(j<n\) 的 \(f_{i,j}\) 答案为 \(f_{i,j}\times n\);对于 \(j\geq n\) 的 \(f_{i,j}\) 答案为 \(f_{i,j}\times \max(j,n)\)。我们用一个 \(g_i\) 表示 \(\sum\limits_{j\geq n} f_{i,j}\),这样做 \(g_{i-1},f_{i-1,n-1}\to g_i\),同时 \(j<n\) 正常转移,就能 \(O(nm)\) 完成 dp。
C
todo:EXKMP,Z 函数
11/6 Day 2
A
题解:首先可以发现这个区间有一定的单调性,也就是说若 \([l_1,r_1]\in[l_2,r_2]\) 且 \([l_1,r_1]\) 合法则 \([l_2,r_2]\) 也一定合法。可以考虑重构区间 2 时只重构包含的区间 1 的部分,其余部分不变也依然合法。
B
题解:通过手推可以发现合法的图一定能满足:在图中能找到一条链,使得每一个点到链的距离都 \(\leq1\)。
考虑这玩意得靠直觉,首先发现链一定可行,又想到题目的这个限制好像蛮强的因为怪物动的挺快;于是想在链上往外延申一些点考虑是否可行;发现延申超过一层就一定炸也就得出了这个结论。
考虑这个该如何维护。
设不在链上的结点为叶子节点,则所有叶子结点的度数都为 \(1\),否则 \(>1\) 的都为链上节点。我们只需要判断是否所有点相邻的 \(d_v>1\) 的点的数量 \(\leq2\),记这个数量为 \(f_u\),则对于每个点都有 \(f_u\leq2\)。
发现如果一个图满足,那么它的任意一个子图也满足,说明有二分性,也就是可以双指针。
双指针加入和删除点的本质其实是加入和删除当前点所有的边。接下来模拟的过程比较抽象。
考虑双指针时加入每条边 \((u,v)\) 时,\(d_u,d_v\) 都 \(+1\)。如果修改完此时 \(d_u=2\) 就说明原来 \(u\) 是叶子,将与 \(u\) 相邻的点的 \(f_{frm_u}\gets f_{frm_u}+1\) 计算贡献,如果 \(d_v\geq2\) 就 \(f_u\) 加贡献;对于 \(d_v=2\) 同理。
考虑删边时 \(d_u\gets d_u-1\),大致同理,考虑修改完 \(d_u=1\),则说明变成了叶子节点 \(f_{frm_u}\gets f_{frm_u}-1\)。
只需要存下来此时有多少点 \(f_i>2\) 然后双指针即可。
C
todo
11/8 Day 3
A
题解:将向量 v 排序后,构建其前缀和数组 s。
由于在同一时刻对同一维度进行多次操作不优,因此无需考虑同时性的问题,只需判断所需增加的距离之和是否足够即可。
一个显然的性质是,随着 k 的增大,需要考虑的维度 i 是单调不增的,且满足 \(i>k\)。因此,我们可以使用双指针维护 \(i\):若满足 \(v_i+1\times i−s_i≤k\times v_i+1\) 或 \(i≤k\),则将 \(i\) 增加 1。
由不等式 \(ans\times k≥ans\times i−s_i\)
可得 \(ans=⌊\dfrac{s_i}{i−k}⌋\)。时间复杂度为 \(O(n\logn)\),瓶颈在于排序。
B
题解:可以考虑从 C 性质入手。由于可以一定不踩黑色,求出 \(nxt_i\) 表示 \([i+1,i+k]\) 中最靠右的白色位置。倍增跳即可。
思考没有 C 性质怎么做,经过长度为 \(len\) 的黑段一定有 \(\lfloor \frac{len}{k}\rfloor\) 个点被踩到,所以把长度为 \(len\) 的黑段缩成 \(len\bmod k\),同理跑 C 性质的做法,然后把 \(\lfloor \frac{len}{k}\rfloor\) 插回去就好。
11/11 Day 4
C
思路:赛时看题发现似乎做过一道 CF 的原,仔细看了一下发现有区别,原题要求“上升子序列个数” \(=X\),这题要求“最长上升子序列个数”,想想区别在哪。
发现原题的做法有启发性。原题上一个连续的单调上升序列贡献是 \(2^k\),那么我们先建一个序列 \(1\to \lfloor\log X\rfloor\),此时若 \(X_i=1\) 也就是 \(X\) 的第 \(i\) 为 \(1\) 时,我们就在序列上 \(i\) 的值后面加入一个 \(\inf-i\),这样就相当于加上了一个 \(2^i\) 的贡献。
我们看此题也可以这样做。我们建一个 \({2,1,4,3,6,5,\dots,\lfloor\log X\rfloor}\) 的序列,此时的贡献为 \(2^{\lfloor\log X\rfloor}\),最长上升子序列的长度为 \(\lfloor\log X\rfloor\)。若 \(X_i=1\) 我们也就想让序列上 \(2i-1\) 的值后面能接上一个长度为 \(\lfloor\log X\rfloor-i\) 的上升子序列,同时这个子序列不会跟 \(>2i-1\) 的数连起来也就是可行的。我们可以让所有 \(X_i=1\) 共用一段上升序列,通过改变这个序列的值来保证不会有不属于 \(X_i=1\) 的点后面会接上这个上升序列后构成新的最长上升子序列。
这样做我们前面的序列长度为 \(2\lfloor\log_2 X\rfloor\),后面的上升序列长度为 \(\lfloor\log_2 X\rfloor\),总共长度为 \(3\lfloor\log X\rfloor\),只能有 \(60pts\)。
我们把 \(\log_2\) 改成 \(\log_4\) 总长变为 \(5\lceil\log_4 X\rceil\) 在这种做法下答案最优,但也只能达到正好 \(295\),拿不到满分。正解应该需要做法上的优化。
赛后:发现并不需要做法上的优化,需要一些卡数量的技巧。最后一个连续的一段可以减掉 \(4\) 个。发现最高位的最后至少一个点一定不会在 LIS 中,删除后一定有 \(p_n=n\),又可以删除,此时少两个点只要 \(289\) 次就能过。