2023SDPT-Round2

未整理完 Day4C Day9BC Day10BC 应该是摆了。

SDOI

Day1

题面

A

爆搜得到答案前几项为 \(1,3,15,105,945,\cdots\),然后找规律推出结果为 \(\Pi_{i = 1}^n 2 \times i - 1\)

证明:使用生成函数推导,设 \(f_{i,j}\) 表示考虑了前 \(i\) 个位置,且左括号数量减右括号数量等于 \(j\) 的所有方案权值和,\(\mathcal F(i)\)\(f_{i,1 \sim n}\) 这一行的生成函数。有 DP 柿子 \(f_{i,j} = f_{i - 1,j + 1} \times (j + 1) + f_{i - 1,j - 1}\),容易发现前面一项相当于求导,所以得到生成函数的柿子 \(\mathcal F(i) = \mathcal F'(i - 1) + x \mathcal F(i - 1)\)。进行配微分操作,两边同乘 \(e^{- \frac{x^2}{2}}\) 得到 \(\mathcal G(i)\),有 \(\mathcal G(i) = \mathcal G'(i - 1)\)。要求的是 \([x^0] \mathcal F_n(x)\),注意到 \(exp \mathcal F(i) = \sum_{k = 0}^{+ \infty} \dfrac{1}{k!} \mathcal F^k(x)\),有 \([x^0] \mathcal F_n(x) = [x^0] \mathcal G_n(x)\)。因为 \(\mathcal G(0) = 1 · e^{- \frac{x^2}{2}}\),对它导 \(2n\) 次就得到了 \(\dfrac{(2n)^{\underline n}}{2^n}\)

B

完全不会,等学会了线代和矩阵树定理回来补,先套壳一个官方的 sol。

我们考虑多一个三元环有什么不同,考虑钦定矩阵树删去的一行列为这三个点里面最大的一个点,那么剩下的两个点对应于删去对应的两行两列,也就是说要求对于一个三元环删去任三行三列主子矩阵之后的行列式。这种小子矩阵的问题,一般我们用打洞技巧处理(实际上就是分块矩阵运算)。

考虑分块矩阵 \(P=\pmatrix{A & B \\ C & D}\),我们假设\(P\)可逆,\(A\) 可逆,做变换得到 \(\pmatrix{A & B \\ 0 & D-B A^{-1} C}\),这当然不改变这个矩阵的行列式。所以 \(|A|=|D-BA^{-1}C|^{-1}\cdot |P|\)

不妨考虑 \((D-BA^{-1}C)^{-1}\) 是什么,看起来当然可以使用同样的技巧:有 \(P^{-1}=\pmatrix{A & B \\ 0 & D-B A^{-1} C}^{-1}\pmatrix{I & 0 \\ A^{-1}C & I}\),所以 \((D-BA^{-1}C)^{-1}\) 当然就对应于 \(P^{-1}\) 的右下角,也就是说我们可以用 \(P^{-1}\) 的子式表达 \(P\) 的余子式,这在 \(1\) 行列的余子式的时候是经典的伴随矩阵。那么我们删去每一行列得到的行列式是一样的,如果我们求得了删去一行列之后的逆 \(P^{-1}\) ,我们能够通过枚举其他删去的两行两列计算一个 \(2\times 2\) 的行列式。

考虑怎么计算删去一行一列之后的矩阵逆,这是一个经典的低秩扰动的问题:\(B=A^{-1}\) 已知,考虑 \((A-uv^T)^{-1}\),其中 \(u,v\) 为列向量。则 \((A-uv^T)^{-1}=(I-A^{-1}uv^T)^{-1}A^{-1}=(I-Buv^T)^{-1}B\)。用 \((I-Buv^T)^{-1}=I+\displaystyle \sum_{i\geqslant 1} (Buv^T)^i=I+\displaystyle Bu\left(\sum_{i\geqslant 1} (v^TBu)^{i-1} \right)v^T\)。中间的 \(c=v^TBu\) 是个常数,考虑计算 \(\dfrac{1}{1-c}\),所以 \((I-Buv^T)^{-1}=B+\frac{Buv^TB}{1-c}\) ,总的计算复杂度是 \(\mathcal O(n^2)\) 的。

用这个来表达删掉行列或者补充行列,只要把删去的行列认为是在那里留下仅一行一列的 \(1\),就能在不改变矩阵大小的情况下快速修改。

C

首先最暴力的想法是暴力预处理每个点不同深度的子孙数量,然后用类似容斥的计算暴力跳着求,复杂度 \(\mathcal O(n^2)\)

在这里能够发现要求的是一段连续的位置,于是先重剖把询问拆到若干条链上,能够发现对于节点 \(A\) 若贡献到答案,记其,必然有 \(\dfrac{dis_{A \to x} + dis_{A \to y} - dis_{y \to x}}{2} \leq k\),整理一下得到 \(dis_{A \to y} + dep_A \leq 2 \times k + dis_{y \to x} + dep_x\),然后符合这个条件的必然是链上的一段前缀,以此柿子作为一维限制,链上 dfn 序作为一维顺序,转化成二维数点,这样是 \(\mathcal O(n \log^2 n)\) 的。

依然先重剖,然后将询问拆成两部分,一部分是对于 \(y\) 单独询问,求 \(y\) 子树内距离 \(y \leq k\) 的点数,转化成 \(y\) 子树内距离 \(y\) 距离为 \(k + 1\) 的点的子树和;另一部分是 \(x \to y\) 链上其它的点,求每个点距离其为 \(k\) 的点的个数数量(直接算 \(\leq k\) 的还要容斥掉一部分)。离线询问计算贡献。对于前者,可以使用长剖或者 dsu on tree,这是一个经典问题;对于后者,先差分一下变成询问前缀,每个重链单独考虑,遍历一遍记录树上轻子树子树大小和,做法是暴力 dfs 然后将大小插入到桶里,和 dsu on tree 相似。两部分复杂度理论上相同,一块就是 \(\mathcal O(n \log n + q)\)

Day2

题面

A

第一反应肯定是取 \(x = a^{\frac{1}{k}}\),然后套壳欧拉定理,有 \(a^{\frac{t(p - 1) + 1}{k}} \equiv a (\mod q)\)。题目前置有 \(k \nmid p - 1\),所以必然存在一个 \(t\) 满足条件,此时直接取 \(t = - (p - 1)^{-1} \mod k\),然后用 exgcd,可以做到 \(\mathcal O(T \log k)\)

B

暴力的想法是 bitset 暴力判断,然后就是喜闻乐见的 \(\mathcal O(\dfrac{n^3}{w})\)。旁边的江苏队爷手写 bitset 压 \(128\) 位,并且加入特殊判断技巧直接卡过去了,感觉很牛逼。场上还有一些传递闭包一类的神秘优化,感觉这个题就很乱搞。标算给了一种四毛子优化。首先有一个定义是若 \(A \supseteq B\),则称 \(A\)\(B\) 的超集,即 \(B\)\(A\) 的子集。考虑按每 \(B\) 个元素分个块,如果 \(S_i \subset S_j\) 那么 \(i\) 在每个块内都是 \(j\) 的超集。处理出 \(n\) 个集合是哪些集合的超集,这样求交就能到 \(\mathcal O(\dfrac{n^3}{wB})\)。预处理如果视为求高维后缀和,那么就是 \(\mathcal O(2^B \times \dfrac{n^2}{w})\) 的复杂度,算一下 \(B\)\(8,9\) 的样子最优。如果用 lowbit 递推预处理的话,就进一步优化到 \(\mathcal O(\dfrac{n^3}{w \log n})\)。感觉就是优化/乱搞题。

C

暴力的写法是 DP,设 \(f_{i,j}\)\((i,j)\) 这个位置的最大收益,\(w_{i,j}\) 为这个格子是不是黑色,转移式子为 \(f_{i,j} = \max{(f_{i - 1,j},f_{i,j}+[w_{i,j} = 1],f_{i + 1,j})}\)。有一个结论是如果碰到一个矩形,那么一路走到底是最优的,证明考虑如果你要中间拐弯,那么不如把这个拐弯延后到白格子的地方,路径上的行走是等效的,但是得分显然矩形内竖直向下更优。依然使用这个暴力 DP 式子,然后用一个扫描线维护,从上往下扫。每个时刻将区间向两边较小的 DP 值扩张。如果遇到矩形则不扩张,一路竖直走到底,最后累加上这段长度。

Day3

题面

A

注意到只需要考虑第一步操作,然后会被分割成两部分小问题。设 \(f_{n,k}\) 直接表示答案,所以有柿子:

\[f_{n,k} = \dfrac{1}{n - 1}([k > 1] + [k < n] + \sum_{i > k} f_{i - 1,k} + \sum_{i < k - 1} f_{n - i - 1,k - i - 1}) \]

使用前缀和优化做到 \(\mathcal O(nk)\)。正难则反,设 \(g_{n} = 1 - f_{n,1}\),即长度为 \(n\) 的球列第一个被染白的概率,由于左右两侧是对称的(打表观察易知),而且在两侧计算是独立的,所以可以转化出 \(f_{n,k} = 1 - g_k g_{n - k + 1}\),转化过来后也可以打表观察柿子,这个东西直接递推求,所以复杂度 \(\mathcal O(n)\)

B

形式化题意是将一张二分图划分为若干条链,使得孤立点尽可能少,且在此基础上长度为 \(3\) 的链尽可能少。显然任意长度大于 \(1\) 的点可以拆成若干条长度为 \(2\)\(3\) 的链,跑一个限制每个点流量不超过 \(2\) 的流,期望有尽可能多的点有非零的流量,可以使用最小费用流。给二分图两部分的点向对应的源/汇连一条流量为 \(1\),权为 \(-\infty\) 的边,这样会优先增广费用小的;再连一条流量为 \(1\) 的,权为 \(1\) 的边,这样在流完前者的情况下会再尽量流这种边,表示构成长度为 \(3\) 的链,盗一张题解的图,连出来大概这样:

p9qMoN9.png

这样直接流显然是会 TLE 的,注意到网络上增广路的长度只有 \(- 2 \times \infty\)\(- \infty + 1\) 这两种,在跑完最短路之后直接用 Dinic 一类算法多路增广即可,这样时间复杂度可以做到 \(\mathcal O(m \sqrt{n_1 + n_2})\)

C

暴力叉积判交是 \(\mathcal O(nq)\) 的,可以拿到 \(25\)。离线询问,按照 x 轴分治,每次考虑只在 \([l,r]\) 区间的子问题,\(l = r\) 的情况是平凡的直接特判掉。记多边形顶点最小/大横坐标为 \(x_l,x_r\),于是现将问题框在 \([x_l,x_r]\) 内。调用 solve(x_l,x_r)

记两条直线 \(\mathcal L : x = x_l,\mathcal R : x = x_r\)。对于任意多边形边或询问线段 \(l\),进行如下操作:

  • \(l\)\(\mathcal L,\mathcal R\) 都相交,在这个区间内直接视为直线,然后干掉它。
  • \(l\) 只与 \(\mathcal L\) 相交,调用 solve(l,mid)
  • \(l\) 只与 \(\mathcal R\) 相交,调用 solve(mid+1,r)

如果多边形边被视为直线,询问被视为线段。由于是简单多边形,所以在这个区间内所有多边形边的直线一定互不相交。二分出询问线段的上/下方第一条直线,然后直接判交即可。

如果询问被视为直线,多边形边被视为线段。依然依靠简单多边形的性质,可以将区间内的多边形部分划分为若干个联通区间,每个区间至少和 \(\mathcal L,\mathcal R\) 中的一个相交。维护每一个区间的 \([y_l,y_r]\),如果询问直线被夹在某一个区间那么一定相交,检查直线左右端点是否被区间覆盖即可。否则直线一定处于两个区间之间的位置,注意到左上/右上/左下/右下都有可能存在区间(这里的左右指的是和左右边界相交所以会分左右),需要判断这个区间的边所构成的折线是否和询问直线相交。注意到直线和一个折线有交,当且仅当与折线端点构成的凸包有交,于是转化成 y 轴上从小往上扫,每个时刻上方会出现新的点,下方会减少点,要动态维护凸包以及和凸包判交。核心在于如何快速合并凸包,对于每个区间预处理出它的凸包,将所有询问直线和凸包按 y 坐标排序,因为是简单多边形,所以合并两个凸包的时候必定存在一个分界点,使得一侧都是原来的点,另一侧都是新凸包的点,直接二分出分界点即可,判交是在凸包上二分看是否有交点。

每条线段都被递归到 \(\log V\) 个区间,每个区间做的复杂度是 \(\mathcal O(n \log n)\),总复杂度 \(\mathcal O((n + q) \log (n + q) \log V)\)

Day4

题面

A

首先复杂度肯定是挂在 \(m\) 而不是 \(n\) 上。\(65 pts\) 是将 \(m\) 条关键边两侧的点作为关键点互相连边,总共是 \(\mathcal O(m^2)\) 的量级;非关键点缩点缩掉(暴力向大一号的连边),然后暴力跑 Prim 即可。

这样的时间问题主要在于会带一个 \(m^2\),考虑使用 Boruvka,这个算法的原理是对于当前的连通块每次找到块内到块外边权最小的边,总共扩展 \(\mathcal O(\log m)\) 轮,关键边的总复杂度即为 \(\mathcal O(m \log m)\)。再回来考虑非关键边,对于点 \(x\),能够成为答案的只有编号上 \(x\) 的前驱和后继 \(y\)\((x,y)\) 不为关键边能够成为答案。如果对于每一个 \(x\) 都暴力找前驱后继的话,复杂度可能达到 \(\mathcal O(m^2)\),因为可能扫到块内的点。不过可以 \(\mathcal O(m)\) 预处理 \(x\) 不在自己块内的前驱后继,于是做到了 \(\mathcal O(m) - \mathcal O(1)\)

总共扩展 \(\mathcal O(\log m)\) 轮,总时间复杂度 \(\mathcal O(m \log m)\)

B

无解的必要条件是成环或者有点初态联通但终态不连通。接下来使用 \(x \to y\) 表示 \(x\)\(y\) 的祖先。

如果 \(x\)\(y\) 的父亲,那么必定存在一步操作是 \(x\) 直接 unite 到 \(y\)。注意到 find 只会批量破坏/修改一串祖先关系,并不能增加新的后代关系,因此如果有限制条件 \(x \to y\) 的祖先,那么必然任意时刻都满足。

如果终态 \(x \to z\),初态 \(y \to z\) 的祖先,那么某一时刻必定有操作使得 \(x \to y\)。由此得到若干组 \(x\) 必须是 \(y\) 的祖先的条件,根据这些条件连边,如果成环了则无解,否则根据拓扑序来构造方案。

如有关系 \(x \to y \to z\) ,可以通过操作 \(z\) 达到 \(x \to y,x \to z\) 而不影响其他结构的效果,注意此处是带着子树一块移动。如果初态和终态都有并查集树形态下非根节点 \(x\) 有爹 \(fa_x\),当且仅当 \(x\) 没有被操作过,因为无论 unite 还是 find \(x\) 都会变爹,由此来判断什么时刻操作 \(x\),即对哪些节点使用 find。在最开始进行全部的 find 一定最优,然后在按照拓扑序来通过 unite 复原。对一个节点至多进行 \(n\) 次 unite,总操作次数毛估估有个 \(n^2 + n\) 的上界。

C

巨大多恶心题。没别的思路,和套官解没啥区别。

\(S\) 为当前局面下所有本质不同的花色数量,\(N\) 为栈的数量,显然当 \(S < N\) 的时候必定有解,因为根据鸽巢原理此时要么存在空栈可以倒腾,要么存在栈顶花色相同可以消掉。记 \(A_i\)\(i\) 花色牌面最大的牌,\(B_i\)\(i\) 花色牌面次大的牌。当 \(S > N\) 的时候必定无解,原因是每种花色的 \(A\) 都不能被消掉,因此至少留下 \(S\) 张牌,依然鸽巢原理,至少有一个栈大小为 \(2\)。于是只需要解决 \(S = N\) 的情况。

Day5

题面

A

首先考虑无解。最极端的情况无非是都挖空了,这时候起点到终点距离即为曼哈顿距离,如果要构造的距离小于这个距离则无论如何也到不了。在原图上 bfs 扩展做最短路,如果要构造的距离大于原图上的距离则无解,因为删障碍只能缩短距离。网格图是一张二分图,所以如果原图距离和要求构造的距离奇偶性不同,也会是无解。其余情况都是一定有解的。

对于任意合法的局面,都存在删掉一个障碍后图仍为好图,且最短路距离要么不变要么减少 \(2\)。通过讨论可以发现对于一个墙,它相邻的四个方块两个相对的是墙,两个相对的是路,就可以删掉这个墙使得最短路减少 \(2\)。这个格子每次可以 \(\mathcal O(1)\) 定位到,然后删除掉再 \(\mathcal O(RC)\) 重新计算最短路长度,复杂度 \(\mathcal O((RC)^2)\)

显然删掉的墙越多,最短路越短。可以先预处理出删墙的顺序,然后二分要删掉多少个格子,于是复杂度变成 \(\mathcal O(RC \log (RC))\)

B

完全不会,等学会了字符串回来补,先套壳一个官方的 sol。

先考虑怎么快速计算一个 \(g(s)\)。考虑计算出所有的 \(a_i = f(s[1,i],s[i + 1,|s|])\)。那么对 \(s\) 建后缀自动机,求出每个点 \(w\) 的 endpos 的最小值 \(m(w)\) 与最大值 \(M(w)\),以及所代表的串长 \([l,r]\)。对于一个节点 \(w\),可以发现其对 \(a[m \cdots M − r]\) 的贡献为 \(r − l + 1\),而对 \(a[M − r + 1 \cdots M]\) 的贡献是一个等差数列。问题变成进行若干次区间加常数与区间加等差数列,最后求值。可以使用前缀和线性完成。于是可以 \(\mathcal O(|s|)\) 计算一个 \(g(s)\) 的值。

转化问题变成最少划分段数是否不超过 \(k\),考虑从起点开始找到最大的 \(r\) 使得 \([l,r]\)\(g\) 值不超过 \(V\),把它记为分界点,并令\(l \leftarrow r + 1\)。考虑如下形式的倍增:

  • \(k = 0,1,\cdots\),尝试 \(r\) 增加 \(2^k\),如果无法增加,立刻停止。
  • \(k' = k,k − 1,\cdots\),尝试 \(r\)增加 \(2^{k'}\)

容易发现通过上述倍增,找一段的复杂度并不是 \(\mathcal O(n)\),而是 \(\mathcal O((r − l) log(r − l))\),于是复杂度即为 \(\mathcal O(n log^2 n)\)

C

常规思路是 \(1 \sim n\) 的素数不超过 \(\sqrt{n}\) 个,预处理出来跑背包,复杂度 \(\mathcal O(n^{\frac{3}{2}})\)。根据这个暴力打表,可以发现答案的数量不超过 \(3\)。答案为 \(1\) 的可以直接查表,使平凡的。答案为 \(2\) 的枚举一个素数 \(Y\),判断 \(X - Y\) 是不是素数,复杂度 \(\mathcal O(\sqrt{n})\)。答案为 \(3\) 的枚举两个素数 \(Y_1,Y_2\) 即可,复杂度也是 \(\mathcal O(n)\) 的,但是跑的飞快,原因是对于 \(n \leq 10^10\),枚举量实际上不超过 \(24\)

\(X = Y_1 + Y_2\),若 \(Y_1\) 长度严格大于 \(Y_2\),容易发现最高位只有两种情况,要么是前面进位上来的,要么是直接是 \(X\) 的这一位,枚举最高位是什么,还可以同时确定最低位,剩余部分就是子问题,除了允许存在前导零,然后就可以相同方式解决;若 \(Y_1\) 长度等于 \(Y_2\),只需关心最高位和最低位是否有进位,而这两个是绑定的,根据 \(X\) 的长度可以知道是否存在进位,所以依旧是只有两种情况。记 \(D = \log X\),每次枚举可以使 \(D\) 减二,所以复杂度为 \(\mathcal O(D \times 2^{\frac{D}{2}}) = \mathcal O(n^{0.151} \log n)\)

这是对于一个长度的枚举复杂度,除此之外还需要枚举 \(X\)\(Y\) 的长度,如果全都枚举,总复杂度达到 \(\mathcal O(n^{0.151} \log^3 n)\)。注意到 \(Y_1\) 的位数只能是 \(D\)\(D - 1\),且如果 \(Y_1\) 的位数远大于 \(Y_2\),可以一次性确定所有多出来的高位,所以复杂度变为 \(\mathcal O(T n^{0.151} \log n)\),位数这么大需要实现高精度。

Day6

题面

A

结论是对于一个限制选在 LCA 上,贪心的优先选取深度大的 LCA。因为一个限制只有不得不选的时候再去选取一定更优,它有更大的概率和更多其他限制有交。证明可以考虑归纳最开始一个都没选的情况。

知道了结论之后就很好做了。最好写的(我的考场)写法是直接剖,然后区间查当前遍历到的 LCA 上面的限制之前有没有被解决。如果挂在上头的所有限制都被覆盖过了就可以跳过,否则需要覆盖,直接单点修改,这个可以直接 BIT,复杂度是 \(\mathcal O(n \log^2 n)\)。官解是拍到 dfs 序上,然后单点查区间加,同样使用 BIT 做到 \(\mathcal O(n \log n)\)。如果能离线 \(\mathcal O(n) - \mathcal O(1)\) LCA,然后用 bfs 暴力扩展标记,这样均摊下来是线性的。

B

\(f_{i,j,k}\) 表示加入了 \(i \sim n\) 的点,目前形成了 \(j\) 个连通块,还有 \(k\) 条边没有定儿子。这样从大到小加点,每次需要考虑的是新点的父亲,左儿子,右儿子。

  • 对于父亲。可以选择父亲比它大,则从 \(k\) 条边中选一条连上;否则则是构成一个新的连通块,暂时认定其没有父亲。
  • 对于左右儿子,是同样的处理方法。可以选择儿子比它大,则从先前的散连通块中选一个并上;否则则是儿子还没有被加入,则会多一条没有定儿子的边。
  • 对于三种不同的状态分别讨论累计转移即可。
  • 直接连可能会出现环或 DAG,这样必然是一个点的父亲和儿子连向了同一个连通块,转移的时候注意系数不选同一个连通块即可。

这样朴素的暴力转移就是 \(\mathcal O(n^3)\) 足以通过,主要还是考状态的设计和转移的细节。被 DP 场创烂了。

C

整式递推/tuu。

形式化题意:

\[\text {given} : ~~~ \begin{gather*} f(x) = \sum_{i = 0}^{x} a^i b^{x - i} c \\ F(x) = \sum_{p_1 + p_2 + \cdots + p_k = x} f(p_1) f(p_2) \cdots f(p_k) \\ \end{gather*} ~~~ \text {figure out} : ~~~ \sum_{i = 1}^{m} \binom{m}{i} F(i) \]

直接暴力 DP 的话,设 \(f_{i,0/1}\) 表示当前长度为 \(i\),当前段是否插蜡烛的权值和,有转移式子:

\[\begin{gather*} f_{i,0} = a f_{i - 1,0} + a f_{i - 1,1} \\ f_{i,1} = c f_{i - 1,0} + (b + c) f_{i - 1,1} \\ \end{gather*} \]

注意到有一档分是 \(b = 0\),设 \(g_i = f_{i,0} + f_{i,1} = (a + c)^i\),则有 \(f_{i,0} = a g_{i - 1}\)\(f_{i,1} = g_i - f_{i,0} = (a + c)^i - a(a + c)^{i - 1}\),用二项式定理快速算。

类比 \(b = 0\),仍设 \(g_i = f_{i,0} + f_{i,1}\),推一推可以得到递推式 \(g_i = (a + b + c)g_{i - 1} - a b g_{i - 2}\),边界 \(g_0 = 1,g_1 = a + c\),答案 \(f_{n,1} = g_{n} - a g_{n - 1}\)

接下来是对官解的套壳,过于 magic 了。

有经典结论,二阶常系数其次递推数列存在通项公式。对于上面形如 \(\mathcal G_x = (\alpha + \beta) \mathcal G_{x - 1} - \alpha \beta \mathcal G_{x - 2}\),可以得到:

\[\begin{cases} \mathcal G_x - \alpha \mathcal G_{x - 1} = \beta (\mathcal G_{x - 1} - \alpha \mathcal G_{x - 2}) \\ \Rightarrow \mathcal G_x - \alpha \mathcal G_{x - 1} = \beta^{n - 2} (\mathcal G_2 - \alpha \mathcal G_1) \\ \mathcal G_x - \beta \mathcal G_{x - 1} = \alpha (\mathcal G_{x - 1} - \beta \mathcal G_{x - 2}) \\ \Rightarrow \mathcal G_x - \beta \mathcal G_{x - 1} = \alpha^{n - 2} (\mathcal G_2 - \beta \mathcal G_1) \\ \end{cases} \]

联立可以得到:\(\mathcal G_x = \dfrac{\alpha^{n - 1} (\mathcal G_2 - \beta \mathcal G_1) - \beta^{n - 1} (\mathcal G_2 - \alpha \mathcal G_1)}{\alpha - \beta}\)

代入 \(a + b + c = \alpha + \beta,ab = \alpha \beta\)。于是得到:

\[\begin{cases} \alpha = \dfrac{1}{2}(a + b + c + \sqrt{(a + b + c)^2 - 4ab}) \\ \beta = \dfrac{1}{2}(a + b + c - \sqrt{(a + b + c)^2 - 4ab}) \\ \end{cases} \]

加法有分配率,\(\alpha\)\(\beta\) 的贡献可以分开算,利用恒等式 \(\sigma_{i = 0}^m \binom{m}{i} a_i = (a + 1)^i\)

对于 \(\alpha = \beta\) 的情况,只会出现在 \(a = b \land c = 0\),此时答案显然为 \(0\)。如果不存在二次剩余,直接扩域即可。总复杂度 \(\mathcal O(T \log n)\)

Day7

题面

A

生日悖论。钦定树有 \(50\) 个点,然后分成两部分,一边 \(24\) 个一边 \(25\) 个,然后给每一部分 shuffle 一个树形态出来,根据生日悖论大概各 \(\mathcal O(\sqrt{998244353})\) 个就好了,然后两个子树内的暴力算 LCA,跨过子树的 LCA 为 \(1\) 可以直接求,然后撞哈希表就行。

为啥一定能有解?该量级下能有约 \(2^{50}\) 个不同哈希值,这个模数肯定能覆盖。用费马小定理也能解释。

B

哥德巴赫猜想。暴力跑出来这个范围是成立的,拿来直接用。首先特判掉 \(1\) 特殊情况和 \(2,3\) 无解,其他情况一定有解。考虑任意 \(\geq 4\) 的偶数能被拆分成两个质数 \(a,b\) 的和的形式,构造方法是从 \(1\) 开始每次加上 \(a\) 并对 \(n\) 取模,这样最后得出来的序列差值只有 \(a\)\(-b\) 两种。奇数将其 \(+1\) 补成偶数后一样操作,然后最后扣掉多出来的一个即可。因为偶数连出来是一个环,叉掉一个得到的链必定也合法。这里的问题在于要保证 \(a,b\) 不同,否则得到的是一个长度
\(< n\) 的循环节,注意到这个范围内(事实上更扩展貌似也)只有 \(4 = 2 + 2\)\(6 = 3 + 3\) 不能拆分成两个不同质数相加,于是这两个数爆搜一下也特判掉即可。

如何证明一定能这样构造一定取到每一个值且没有重复?考虑每次加 \(a\) 一定会改变一次模 \(b\) 的等价类,考虑到 \(a \% b,2a \% b,\cdots,ab \% b\) 一定互不相同的,所以操作 \(n\) 次后得到的必定是 \(n\) 的排列。

C

完全不会,等学会了多项式回来补,先套壳一个官方的 sol。

首先,放棋子的方案数和染黑位置无关,只与个数有关,因此可以直接组合数算出放 \(k\) 个黑点的方案数。然后是棋子,有些位置不能填,也可以通过容斥求出方案数。拆出容斥的每个系数,可以用 NTT 卷积优化上述过程。这样复杂度就变成了 \(\mathcal O(n \log n)\)

Day8

题面

A

去掉既出现又离开的,剩下的只有三种:已经加入还没出去;确定未来某个时刻出去,前面并未确定什么时候加入;从未出现过,既没加入也没出去。考虑从左向右扫一遍 DP。假如说没有第二种操作,那么这个是简单的,直接设 \(f_{i,j}\) 表示当前考虑到了第 \(i\) 个位置,目前还有 \(j\) 个没有确定什么时候出去。现在带上了第二种操作,就需要在前面预留出一些位置,使得未来可以和这些操作配对;这样碰到一个第二种操作,就只需要在前面预留出的位置随便选一个就行。于是状态变成了 \(f_{i,j,k}\) 表示当前考虑到了第 \(i\) 个位置,前面预留出了 \(j\) 个位置给第二种操作,目前还有 \(k\) 个没有确定什么时候出去。转移直接分类讨论当前位置进行什么操作,这样得到了一个 \(\mathcal O(n^3)\) 的做法。

事实上如果写出这部分之后对着样例输出所有的 DP 值,能够发现很多位置都是 \(0\),这是因为所有的 \(i,j\) 都能对应唯一一个 \(k\)。于是可以压掉一维,复杂度就变成了 \(\mathcal O(n^2)\)

B

\(dist(x,y)\)\((x,y)\) 间的树上距离。

考虑当直径为偶数时怎么做。令 \(L\) 为直径,显然此时 \(D = L/2\)。对每个点设一个权值 \(w_u\),如果有 \(u \to v\),那么 \(w_v − w_u = 1\),显然当固定一个点的 \(w = 0\) 时所有 \(w\) 与定向方案构成双射。那么可以发现 \(d(u, v) = (dist(u, v) + w_u − w_v)/2\)。又因为直径是偶数,所以移项后得 \(|w_u − w_v| \leq L − dist(u, v)\),这是方案合法的充要条件。找到直径上的中点 \(m\),于是可以发现所有距离 \(m\)\(D\) 的点的 \(w\) 值相同,于是钦定它们的 \(w = 0\),于是有 \(|w_u| ≤ D − dist(u, m)\)。同时注意到 \(|w_u − w_v| ≤ |w_u| + |w_v| ≤ 2D − dist(m, u) − dist(m, v) ≤ 2D − dist(u, v)\),于是条件仍然是充分的。所以这也是充要条件。
直接 DP 即可,时间复杂度 \(\mathcal O(n^2)\)

直径是奇数的情况可以类比着做。首先找出直径上的两个中心 \(m_1, m_2\),令 \(S_1, S_2\) 分别表示距离 \(m_1, m_2\) 更近的点集。于是当 \(m_1, m_2\) 分别作为中心分析的时候,有以下两种条件:

  • \(u \in S_1\),那么 \(|w_u| \leq D − 1 − dist(u, m_1)\)
  • \(u \in S_2\),那么 \(|w_u| \leq D − dist(u, m_2)\)
  • \(u \in S_1\),那么 \(|w_u| \leq D − dist(u, m_1)\)
  • \(u \in S_2\),那么 \(|w_u| \leq D − 1 − dist(u, m_2)\)

注意两种情况可能有交集,压紧限制再多算一遍交的部分即可。

C

考虑不带修怎么做。记 \(f_{i,c}\) 表示 \(i\) 子树中颜色为 \(c\) 的点的数量,\(g_{i,c}\)\(i\) 的祖先中颜色为 \(c\) 的点的数量。假设钦定所有 \(2\) 都选成 \(1\),则每个 \(0\) 会贡献 \(F_i = f_{i,1} + f_{i,2}\)。考虑不断调整再选成 \(0\) 来达到最优解,假设一个点的祖先全部调成了 \(0\),则贡献为 \(G_i = F_i - g_{i,0} - g_{i,2}\),注意到后代的 \(G\) 一定小于祖先的 \(G\),因此可以贪心的选上所有 \(G_i > 0\)\(i\)。答案即为 \(\sum_{c_i = 0} F_i + \sum_{c_i = 2} \max(G_i,0)\)

再考虑带修怎么做。需要动态维护 \(F,G\),使用询问分块,每 \(B\) 个询问后暴力重构计算 \(F,G\),将这 \(B\) 次修改的 \(B\) 个点拉出来建虚树,虚树外的点形成了若干个连通块,这也是 \(\mathcal O(B)\) 量级的,于是要做的是对这些连通块做整体的 \(F,G\) 加一或减一。整块 \(F\) 加,可以记录块内 \(c = 0\) 的点个数来维护;整块 \(G\) 加,维护一个 \(H_x = \sum [G_i == x]\),于是求的答案是 \(H_x\) 的一段后缀和,每次 \(G\) 的整体修改只会更改后缀和的起点,这个变化也是 \(\mathcal O(B)\) 量级的。

时间复杂度 \(\mathcal O(\dfrac{qn}{B} + qB)\),取 \(B = \sqrt{n}\),总复杂度为 \(\mathcal O(q \sqrt{n})\)

Day9

题面

A

最小值显然是每次选一个叶子向上染,且每个叶子只染一次。注意到每条边都需要染色,并且重复染无效,所以对于一个子树,只有第一条延伸到子树外的边会关心子树外的信息,其他的边都划归到子树内的子问题。考虑树形 DP,设 \(f_{i,0/1}\) 表示对于子树 \(i\) 第一条延伸出去的边是白色/黑色的答案。转移的话对于 \(i\) 的儿子 \(j\),分别记录边 \((i,j)\) 染上黑色白色的答案,然后考虑到底是选择哪条链作为第一条延伸出去的。设 \(g_i\)\(i\) 子树内的叶子结点数量,于是选择 \(j\) 的概率为 \(\dfrac{d_j}{d_i}\)。对于不是第一条延伸出去的链,可以直接在子树内算完它的选择方案数,即 \(i\) 的深度。时间复杂度 \(\mathcal O(n)\)

B

如果在一个方向走到头了,接下来就会一直往另一个方向走了。由于转向对长度差的限制,所以一次行走至多转向 \(\log V\) 次。转化成记录全局从 \(s\) 出发后所有的转向点,然后区间的限制相当于找从 \(s\) 出发第一个在区间外的转向点,然后路线就行如先正常转向走,然后到这个转向点是走到这个方向的边界线上,然后再反方向走向另一个边界线。预处理转向点的方法

C

Day10

题面

A

先转化成两只青蛙从起点开始跳,并且每次钦定靠后的青蛙跳。暴力是设 \(f_{i,j,k}\) 表示第一只青蛙在 \(i\),第二只青蛙在 \(j\),两只青蛙的步数相差 \(k\) 的最大权值,答案即为 \(f_{n,n,0}\)

考虑如何优化。首先显然有 \(|i - j| \leq B\)。对于一个处于 \(i\) 的青蛙,可以发现剩下可以走的木桩数量 \(n - i\) 很大程度上固定了青蛙还需要的总步数。根据二元一次不定方程可知,如果要改变步数就需要将 \(\dfrac{A}{g}\) 次跳 \(B\) 步换成 \(\dfrac{B}{g}\) 次跳 \(A\) 步,其中 \(g = \gcd(A,B)\)。通过这个也可以知道每个位置可能的步数只有 \(\mathcal O(\dfrac{ng}{AB})\),合法的跳跃位置只有 \(\mathcal O(\dfrac{n}{g})\) 个,转移是 \(\mathcal O(1)\) 的,所以复杂度 \(\mathcal O(\dfrac{n^2g}{ABg}) = \mathcal O(\dfrac{n^2}{A})\)

B

C

posted @ 2023-05-24 14:59  LgxTpre  阅读(13)  评论(0编辑  收藏  举报