清华集训2016~2017选做
Alice和Bob又在玩游戏
先考虑暴力怎么做,枚举每个节点做根节点,然后求其子树内 \(SG\) 值,也就是枚举每一个节点,然后求剩余子树 \(SG\) 值的异或和。最后求 \(mex\) 即可。
考虑优化,每一次合并两个子树,每个子树用一个 \(01-Trie\) 表示所删去每一个点的答案,然后新加一个子树相当于给这个子树所有的答案异或上合并上来的那棵树的异或和,合并上来的树同理,然后在用 \(Trie\) 合并将两棵子树合并。这些操作都可以简单的采用 \(Trie\) 树完成。
如何优雅地求和
将 \(f(x)\) 求出来,一次考虑每一个系数,于是问题转化为求
\(k^i\) 不太对劲,将其拆开,表示成:\(k^i=\sum_{j=0}^k\begin{Bmatrix}i\\j\end{Bmatrix}k^{\underline{j}}\),带入可得,原式等于:
直接递推斯特林数求和即可。其实可以通过下降幂求和做到 \(O(NlogN)\),但是懒得打 \(Latex\) 了
石家庄的工人阶级队伍比较坚强
考虑我们需要一个操作,来表示获胜,平局和失败的共同点,由于将获胜反过来就是失败,所以肯定不能采用满足交换律的操作,发现三进制不退位减法就可以很好地表示输赢,具体的,如果 \(a-b=1\) 则 \(a\) 获胜,\(a-b=2\) 则 \(b\) 获胜,\(a-b=0\) 则平局。设 \(F_i(x)\) 表示 \(x\) 三进制下 \(i\) 位的数量,于是我们每一轮操作就是:
其中 \('+'\) 表示不进位加法,\(B_l=b_{F_1(l), F_2(l)}\)。这里就已经可以看出是一个三进制 \(FWT\) 了,三进制 \(FWT\) 构造的矩阵就是范得蒙得矩阵,考虑怎么计算 \(w_3^1\),根据单位复根的性质,有 \(1+w_3^1+w_3^2=0\)。于是可以解出 \(w=\dfrac{-1+\sqrt{-3}}{2}\)。设 \(y^2=-3\),那么给每个数赋值为 \(ay+b\),然后采用这种二维操作即可。
温暖会指引我们前行
字典序最大,等价于求最大生成树,直接用 \(LCT\) 维护即可。
组合数问题
考虑 \(k\) 很小,采用 \(Lucas\) 定理,将所有组合数拆分成 \(k\) 进制的形式。\(\dbinom{i}{j}\) 是 \(k\) 的倍数等价于 \(i\) 的 \(k\) 进制拆分之后,存在一位比 \(j\) 的 \(k\) 进制拆分小。
数位 \(DP\),设 \(dp[i][0/1][0/1][0/1]\) 表示考虑到 \(k\) 进制的第 \(i\) 位,第一个数是否有最高位限制,第二个数是否有最高位限制,前 \(i\) 位是否存在一位 \(i\) 比 \(j\) 小,直接转移即可。
汽水
给每条边权值减去 \(k\),问题等价于平均边权尽可能接近 \(0\)。采用分数规划,对大于 \(0\) 小于 \(0\) 分别做一遍,每次相当于求最长路径,可以采用点分治,然后跑双指针判断是否存在对应的路径。
生成树计数
考虑贡献只和度数相关,那么考虑 \(prufer\) 序列。假设 \(prufer\) 序列为 \(\{c_i\}\),那么答案可以写成:
后面的 \(\sum\) 看起来很不友好,将其拆开,可以得到:
设 \(F(x) = \sum_i\dfrac{(i+1)^{2m}x^i}{i!}, G(x)=\sum_{i}\dfrac{(i+1)^{m}x^i}{i!}, S(x)=\prod G(a_i\ x)\),那么答案可以写成:
考虑 \(S(x) = \exp\big(\sum\ln G(a_i\ x)\big)\),那么我们求出 \(\ln G(x)\) 和 \(\dfrac{F(x)}{G(x)}\)。只需要对 \(k=0\sim n - 2\) 求出 \(\sum a_i^k\) 即可。
这是一个经典问题,设 \(A(x) = \sum a^kx^k=\dfrac{1}{1-ax}\),那么我们需要求的式子即为 \(\sum \dfrac{1}{1-a_ix}\),直接分治 \(NTT\) 通分即可求出答案。
无限之环
对于网格图,先将其二分图染色,把每个方格拆分成四个点,分别表示上下左右。由于直线型不能旋转,其余形状每次旋转只有一个点会发生变化,将会发生变化的那两个点连边,边权为需要转的次数,最后图不存在漏水当且仅当每一个黑白出口都进行了配对。
一条增广路的意义是从白点出发匹配一个黑点,对这张图跑最小费用最大流即可,如果满流则说明合法。
小 Y 和二叉树
先找到最小的度数小于 \(2\) 的节点,将其当作根节点,然后这个节点的儿子所连接的两棵子树为变成两个独立的子问题。比较两个子树中,叶子深度最小的那个,逐个确定每一位。那么只需要求出每个子树内叶子节点的最小值即可。
小 Y 和恐怖的奴隶主
设 \(dp[i][j][k][l]\) 表示考虑到第 \(i\) 天,有 \(j\) 个一滴血的, \(k\) 个两滴血的,\(l\) 个三滴血的,然后用矩阵转移即可,注意这里状态总量是 \(166\) 个,需要用向量乘矩阵的套路。
榕树之心
考虑 \(u=1\) 怎么判断,子树内的元素可以相互抵消,那么设 \(f_i\) 表示考虑到 \(i\) 点的子树内,抵消之后最少剩下多少次操作(显然最大是子树大小,范围内所有奇偶性相同的都可以达到)直接分类转移即可。
考虑 \(u\ne 1\) 的情况,此时把 \(1\sim u\) 想象成一个新的根节点(也就是缩在一起),最开始先把心移动到 \(u\) 点,做刚刚的 \(dp\) 即可。直接做是 \(O(N^2)\) 的,发现对答案有影响的只有重儿子,对每个点维护一个重儿子和次重儿子即可。
某位歌姬的故事
一段区间的最大值为 \(x\),等价于一段区间所有数都不超过 \(x\),且存在一个数等于 \(x\)。只有第一个限制很好处理,对于第二个限制可以考虑容斥。
先将值域离散化,对于每个区间存储区间长度 \(l\) 以及区间内的数不能超过 \(x\)。\(x\) 小的区间不会对 \(x\) 大的区间产生影响,那么我们从小到大处理每一种 \(x\),然后将其删去,最后将所有的方案乘起来即可。
对于区间内数不超过 \(x\) 的区间,问题可以等价于,有一个长度为 \(n\) 的序列,每一段区间至少放入一个黑球,其余部分放入白球,一种方案的贡献是 \((x-1)\) 的白球个数次方。
于是设 \(f_{i, j}\) 表示考虑到 \(i\),上一次放入 \(x\) 是在节点 \(j\),每次枚举当前位置放不放黑点,然后前缀和优化转移即可。