last
1. 7.28 T3
先差分,转化为 \(n + 1\) 个变量 \(x_1, x_2, ..., x_n, x_{n + 1}\) 满足 \(x_i \le a_i, a_{n + 1} = R\),且 \(\oplus_{i = 1}^{n + 1} x_i = 0\)。
从高位向低位考虑且保持 \(x_i \le a_i\),设最高位为第 \(60\) 位,最低位为第 \(0\) 位,已经考虑了 \(60 \sim i + 1\) 位,现在考虑第 \(i\) 位的情况。下面 我们称一个 \(x_i\) 解除限制 当且仅当 \(x_i\) 和 \(a_i\) 在已经考虑的位上面有一位不同。观察一下,当在考虑到第 \(i\) 位时,存在某个 \(x_i\) 解除限制,那么这一位的异或和就一定可以满足条件。否则需要考虑这一位是否满足本来的异或和就是 \(0\)。我们设最先解除限制的 \(x_i\)(可能有多个)在第 \(i\) 位解除限制,且 \(\oplus a\) 的最高位是 \(D\),那么一定要有 \(i \ge D\)。且当 \(i > D\) 时一定要选偶数个位置同时解禁,当 \(i = D\) 时一定要有奇数个位置同时解禁。
形式化的,设 \(T_i\) 为 \(x_i\) 解禁的时间(\(T_i = -1\) 代表 \(x_i = a_i\)),则 \(\max T > D\) 时有偶数个最大值,\(\max T = D\) 时有奇数个最大值。现在按住 \(T\) 序列,考虑怎么算方案数,经典的,假设某一位上面有 \(c\) 个解禁的 \(x_i\),则前 \(c - 1\) 个随便选 \(01\) 中的一个,第 \(c\) 个看情况选,因此方案数为 \(2^{c - 1}\)。把贡献拆给每一个 \(x_i\), 总共贡献是 \(2^{-\max T}\prod 2^{\max\{T_i, 0\}}\)。按住 \(T_i\) 最大值为 \(M\),考虑直接在最大值处计算,那么已经是最大值的贡献已经确定,不是最大值的 \(T_i\) 可以取 \(-1 \sim M\) 里面 \(x_i\) 和 \(a_i\) 这一位都是 \(1\) 的,把这些贡献加起来就是这一个位置的贡献。然后是算偶数个/奇数个最大值的贡献,那么设 \(f_{i, 0/1}\) 是考虑了 \(x_{1...i}\),选了偶数个/奇数个最大值的方案数总和,简单 dp 即可。
那么考虑多组询问,不难发现 \(1 \sim n\) 的每一位的信息可以提前求出来,然后和 \(n + 1\) 的信息 \(O(1)\) 合并。
时间复杂度 \(O(n \log V + q \log V)\)。
题外话:luogu 上面有一个题要求你支持单点修改和区间询问,这个做法可以直接加个线段树沿用过去,做到下 \(O((n + q) \log n \log V)\)。
2. Yundou Bronze
T1
注意到 \(f(i + 2) = \frac{A_i}{2^{i + 2}} a + (1 - \frac{A_i}{2^{i + 2}}) b\),其中 \(A_i = A_{i - 1} + 2A_{i - 2}\)。显然 \(A_i\) 一直是奇数,判断 \(a - b\) 有多少个 \(2\) 作为因子即可。
闹麻了,t1 是最难的题。
3. hdu round2
1001
对于 \(4\) 种 \((y, z)\) 分别有不同限制,不限制的直接不连边即可,然后做 2 - sat。
1002
现在做到的最优时间复杂度:\(O(n^2)\)
考虑转移:\(f_i = \sum_{j = 1}^{i - 1} g_j \times \sum_{t = j + 1}^i 10^{i - t}a_t\)。注意到 \(f_i = 10f_{i - 1} + a_i\sum_{j = 1}^i g_j\),可以 \(O(n^2)\),因为 \(n = 10^5\) 且 TL = 12s 所以我不知道能不能过了。
好的,正解是考虑不分层转移,而是直接设状态转移。设 \(f_{i, j}, g_{i, j}\) 分别为考虑/不考虑最后一段的贡献的答案。那么转移分两种。设 \(F_i(x) = \sum_{j = 0}^i f_{i, j} x^j, G_i(x)\) 同理。那么 \([F_i, G_i] \to [F_{i + 1}, G_{i + 1}]\) 可以用矩阵表示,但是矩阵里面有一个一次项。设 \(M_i\) 为第 \(i\) 个转移矩阵,那么分治求出 \(l \sim r\) 的矩阵乘积,每一层的多项式大小是 \(r - l + 1\) 的,时间复杂度 \(O(n \log^2 n)\)。
1003
将 \(b_i\) 视为二进制下的字符串,先 reverse,问题相当于最小化 \(\sum 2^{lcp(b_i, b_{i + 1})}\),上 trie,那么假设一个节点既有 \(0\) 也有 \(1\) 儿子,那么显然先跨子树配对,然后多的那一边递归,放什么是不重要的,因此可以先不放。令 \(\operatorname{solve}(u, k)\) 表示删掉 \(k\) 个的最小值,若有两边,则尽量删掉多的那一边。都是单侧递归所以不用考虑合并问题。时间复杂度?\(O(n \log V)\),但是 \(n = 5 \times 10^3, V = 2^{50}\)?
什么叫 \(\texttt{bonus:做到} O(n \log V)\),我来写一下。
好的,我考虑少情况了,如果存在相同数的话会有点问题,不过大差不差了,就记录子树里面有多少个不同数字和总共有多少个数。记左子树的不同数字个数为 \(unq_{ls}\),数字个数为 \(siz_{ls}\),右子树同理。不妨设 \(unq_{ls} > unq_{rs}\)。不难发现如果左子树和右子树的不同数字不够匹配,那么把右子树的相同数字拆出来和左边匹配是更优的,因为考虑左子树本来没有匹配的两个数,贡献至少是 \(2^{w + 1}\) 的,而匹配后三个数的贡献总共只会是 \(2^w + 2^w = 2^{w + 1}\)。所以不够匹配的话,就拆出来匹配就好了,如果还是不够就继续递归,所以这个问题其实可以做到在线加入删除数在线查答案的。
时间复杂度还是 \(O(n \log V)\)。
1005
可以先去重和排序,令变量 \(X\) 为操作的 \(x\) 的和,\(p\) 表示 \(1 \sim p\) 已经被删除,每次操作不减掉 \(a_i\)。那么相当于 \(p\) 不断向右扫,每次最多增加一。两个人没有必要在空隙中博弈,有用的操作只有把 \(X\) 变成 \(a_{p + 1} - 1\) 或 \(a_{p + 1}\)。考虑 \(a\) 中有若干值域连续的段,那么一个人是不想第一个进入奇数段的,而先进入偶数段显然是优的。不难发现,若先手没有一开始就进入奇数段,那么一定胜利。形式化的,先手胜利的条件为:\(a_1 > 1\) 或 \(a_1 = 1\) 且 \(\min\{p | a_p > p\}\) 为奇数。
考虑计数,设有 \(m\) 个 \(a_i = 0\) 的位置。
假设 \(a\) 中没有 \(1\) 的情况,我不选 \(1\),后面随便选都行,方案数为 \((n - 1)^m\)。
接下来考虑选 \(1\) 或者就是有 \(1\) 的情况。枚举我填满了 \(1 \sim V\),且 \(V + 1\) 不存在的情况,设 \(1 \sim V\) 有 \(t\) 个空位,则 \(t\) 个值每个至少有一个,而剩下的 \(n - 1 - t\) 个值有没有都可以,使用插板法即可,方案数为 \(\binom{m + n - 1 - t - 1}{n - 2}\)。
时间复杂度 \(O(n)\)。
好吧我错了,这个东西不能直接算,这里是少乘了个多重集排列。正解应该是容斥,然后把关于 \(t\) 的柿子提取出来,然后里面是一个卷积的形式,使用 \(\texttt{ntt}\) 提前算出来,时间复杂度 \(O(n \log n)\)。
1006
考虑找到最大的 \(L\),满足 \(L^3 \le n\),然后构造 \(\texttt{h...hd.....du....u}\),长度为 \(3L\)。注意到 \(n = 10^9\) 时合法,而小于它时至少还有 \(4\) 个空位可以放。令 \(n \gets n - L^3\)。然后再找到最大的 \(k\) 满足 \(k_1L^2 \le n\),其中 \(k_1 \in [0, 3]\)。
先考虑 \(k \in [1, 2]\) 的情况,直接放在 \(u\) 处即可,最多花费 \(2\),继续 \(n \gets n - k_1L^2\),然后是找到 \(k_2 L \le n\),直接花费 \(1\) 放个 \(\texttt u\) 在 \(\texttt d\) 段对应的位置即可。
4. 8.15 t3
还有人类吗。
先考虑 \(q = 1\),现在操作的本质是每次将一个黑点往下推,而且不能进入有黑点的子树去推子树的黑点。dp,考虑设 \(f_u, g_u\) 分别是 \(u\) 是黑点(可以移动)/白点的答案,注意黑点的 \(g_u = -\infty\),再设 \(s_u\) 为子树完全不动的时候的答案。\(g_u\) 是儿子中是黑点的 \(f_u\) 以及白点的 \(g_u\) 的和,\(s_u\) 容易算出。\(f_u\) 的转移就有两种,一种是完全不动,这种是好算的。然后就是推向某个不是黑点的子树,这种贡献是 \(g_u + \max\{f_v - g_v\}\)。时间复杂度 \(O(qn)\)。
然后优化,显然我们需要考虑一个与 \(\sum m\) 有关的算法,上虚树。一个子树内全是白点的 \(g_u = s_u = 0\), 因此 \(s_u, g_u\) 容易求出的,难点在于求出 \(f_u\)。发现 \(f_u\) 第一种转移还是好算的,主要是第二种转移,注意虚数上的一条边是一个链,因此我们不能贸然直接按照原来的方法转移。分讨一下,首先我们可以将黑点移到 \(u\) 的子树中任何一个不在虚树上 \(u\) 的儿子 \(v\) 的子树和链上的点,这样就可以不影响任何转移,则转移相当于取里面的最大值加上原来的贡献。第二种情况是我们阻挡了一个 \(v\) 的子树的去路,其他不变,则转移相当于将 \(v\) 的贡献变成 \(s_v\),并加上链的最大值。第三种情况是我们把黑点推向了 \(v\) 是白点的子树,相当于贡献由 \(g_v\) 变成了 \(f_v\)。
我们发现最难的就是第一个转移是最难算的,后面的显然都可以上 dfs 序 + 线段树。然后考虑子树中的点的 dfs 序是一个区间,注意到一个区间扣掉 \(x\) 个区间会变成 \(O(x)\) 个区间,则我们考虑将链拆成 \(O(\log n)\) 个区间然后直接扣掉,显然我们总共扣掉的区间是 \(O(\sum m \log n)\) 的,因此时间复杂度是 \(O(\sum m \log^2 n + q \log n)\)。
5. P15948 Baker
每次相当于取出结束时间 \([T, T + L]\) 区间中的所有数做这个过程,下令 \(t_i \gets t_i + L\)。建二分图左部点表示每个请求,右端点表示第几个面包的出炉时间,相当于求最大匹配,用公式 \(r - l + 1 - \max_{S \subseteq [l, r]} {|S| - |N(S)|}\)。注意到邻域是一段前缀,只与 \(S\) 中的最大值有关,因此取前缀显然最优。也就是:\(r - l + 1 - \max_{i \in [l, r]}{i - l + 1 - \lfloor \frac{t_i - T}{x} \rfloor}\),化简一下变成 \(r - \max_{i\in[l, r]}{\lceil \frac{ix - t_i + T}{x} \rceil}\)。
问题转化为求区间 \([l, r]\) 中 \(ix - t_i\) 的最大值。如果之间上线段树套李超树就是 2log 的。但是注意到 \(L\) 是个常数,所以询问区间的左右端点都是单调递增的,那么可以直接 Baka's trick 优化成 \(O((m + q) \log m)\)。但是这样可能还是不足以通过,出题人想让我们做的是 \(O(m + q \log m)\) 的,而想要做到这个复杂度则需要注意到 \((i, -t_i)\) 这些点都是单调的,可以直接单调栈做,用 Baka's trick 可以避免删除而变成撤销,每个点只会被加入单调栈两次,撤销两次,询问时直接二分,因此复杂度为 \(O(m + q\log m)\)。
6. 2026.9.5 D
评价:B < D < C < A
先将图反着建,区间加边考虑线段树分治,题目的条件等价于在每个时刻图都是由若干条链组成,并且对于 \(u\) 时刻,\(u\) 一定是某条链的链头,合并两条链是 \(O(1)\) 的,\(k = 0\) 时答案是在 \(u\) 时刻 \(u\) 所在链长的和,那么可以在 \(O(m \log n)\) 时间下解决 \(k = 0\)。
\(k > 0\) 时每次花费 \(1\) 可以在某个时刻合并两个链,显然在时刻 \(u\) 合并到 \(u\) 上是最优的。不难发现本质不同的链的个数只有 \(O(m \log n)\) 个,这是因为每个操作只能导致一条新链的产生。维护出每条链的存在时间,考虑每次新建一条链的时候将存在时间设为当前线段树上对应的时间区间,并在被操作时扣掉区间即可。那么最后将所有链按长度排序并从大到小贪心即可。时间复杂度为 \(O(m \log n \log m )\)。

浙公网安备 33010602011771号