清华集训2017做题记录
清华集训2017做题记录
已完成
- 【清华集训2017】生成树计数
- 【清华集训2017】无限之环
- 【清华集训2017】Hello world!
- 【清华集训2017】小Y和地铁
- 【清华集训2017】小Y和二叉树
- 【清华集训2017】小Y和恐怖的奴隶主
- 【清华集训2017】简单数据结构
- 【清华集训2017】避难所
- 【清华集训2017】榕树之心
- 【清华集训2017】某位歌姬的故事
未完成
Orz \(\text{pinkex}\) 早就切穿清华集训,遥遥领先。
【清华集训2017】生成树计数
左转LOJ讨论区生成树计数最优解法
考虑如果生成树的权值只有 \(\prod_{i=1}^n d_i^m\) ,那么可以用 \(\text{prufer}\) 序列来做,考虑第 \(i\) 个点在 \(\text{prufer}\) 序列中分配了 \(d_i\) 个位置,那么贡献就是 \((d_i+1)^m\) ,又由于一个大小为 \(a_i\) 的联通块选一个点的方案数是 \(a_i\) ,所以在第 \(i\) 个联通块的指数型生成函数就是
我们要求的就是
提出一下公因子 \(\prod_{i=1}^na_i\) 就是
回到原题,生成树的权值是将某一个生成函数的 \((k+1)^m\) 改成 \((k+1)^{2m}\) ,对于每一种情况的 \(Ans\) 的和。
记 \(F'(x)=\sum_{k} (k+1)^{2m}\frac{x^k}{k!}\) ,那么答案就是
这个式子有点复杂,常数项先不管,先处理左边。
对于右边 记 \(G(x)=\frac{F'(x)}{F(x)}\)
本质上都是要求对于一个函数 \(A(x), \sum_{i=1}^n A(a_ix)\) 。
这个东西等价于
记 \(B_i(x)=\sum_{k} a_i^kx^k=\frac{1}{1-a_ix}\) ,也就是求
\(B_i(x)\) 的和直接分治FFT维护分子和分母最后再求逆即可。
【清华集训2017】无限之环
黑白染色后转成二分图模型,每一种类型的水管旋转相当于花费一些代价把本来在一个出口的流量转移到另外一个出口,然后对应出口直接连边。这样从 \(S\) 转移到 \(T\) 的流量就是闭合的接口对数,只要保证所有接口对都闭合即可。
灰色的边是一条代价为 \(1\) 的流量转移边,每一种本质相同的水管的连边方式如下,然后跑费用流就好了。
第一行第三个图好像画错了,那一条长的连边应该改为从右边的出口到上边的出口。
【清华集训2017】Hello world!
分块题,设一个 \(k\) 的阈值 \(S\) ,如果 \(k \geq S\) ,写长链剖分 \(\mathcal O(1) k\) 级祖先,就可以花费 \(\mathcal O(\frac{n}{S}+\log_n)\) 的代价暴力跳跃完成修改和查询。如果 \(k < S\) ,我们发现每一个数最多被开 \(6\) 次根号就变成 \(1\) 了,可以维护 \(S\) 个并查集把所有为 \(1\) 的节点缩起来,每次查询第一个不为 \(1\) 的节点修改,这样均摊是 \(\mathcal O(6n\log n)\) 的。对于 \(k < S\) 的询问操作,我们需要建 \(S\) 张新图,第 \(i\) 新图每个节点的父亲是原先的 \(i\) 级祖先,对每个新图用一个树状数组维护答案,那么这样每一次询问的是 \(\mathcal O(\log_n)\) 的,由于每一次有效修改过后要维护这些树状数组所以修改的均摊复杂度变成了 \(\mathcal O(S\log_n)\) 的,所以总复杂度是 \(\mathcal O(nS\log n+q\frac{n}{S}+q\log n+n\log^2 n)\) ,要想通过\(\text{UOJ}\)数据的话推荐 \(S\) 取 \(128\) 。
【清华集训2017】小Y和地铁
首先理解清楚题意,删去所有只出现一次的换乘站,每一堆换乘站之间连一条合法曲线,使得所有曲线的交点最少。不难发现最优解中只包含四种情况,向上/下连个圈,先绕到一边然后再连个圈。排序以后发现对后面的连法贡献不同的只有两种,所以每次在这两种中调一种,并且那当前受到贡献最少的那个去算就好了。用树状数组维护的话复杂度是 \(\mathcal O(T2^{\frac{n}{2}}\log_n)\) 。
【清华集训2017】小Y和二叉树
首先答案的第一位一定是编号最小的度 \(\leq 2\) 的节点,我们先假装根是这个节点,然后再微操一下,把根换到适当的位置,我们发现,如果当前的假装根是一个度为 \(3\) 的节点,那么这个假装的根是不合法的,需要从两个儿子里选一个走一下去,显然没被走的儿子会先被中序遍历到,那么就取编号最小的度 \(\leq2\) 的节点较大的那个子树走下去。否则我们可以选择以当前节点作为根,或者走唯一的那个儿子,如果选择走唯一的那个儿子,当前位的下一位就是儿子,否则当前位的下一位是对应子树里面编号最小的度 \(\leq 2\) 的节点,比较两者的编号选择走或不走即可,那么我们就找到了一个根,贪心的决定左儿子/右儿子输出方案即可。
【清华集训2017】小Y和恐怖的奴隶主
记录 \(x, y, z\) 表示 \(1,2,3\) 点生命值的奴隶主的数量作为状态,发现状态数不是很多,于是可以矩阵乘法。对于询问。预处理出 \(2\) 的幂次对应的矩阵,每次就是矩阵乘向量,优化后复杂度是 \(\mathcal O(S^3\log n+TS^2\log n)\) ,卡卡常数就过了。
【清华集训2017】简单数据结构
乱搞题,维护一下每个元素是否在集合中以及在集合的位置,并且维护每一种 \(dp\) 值的数量。考虑左端插入因为保证了相同元素的插入次数限制,所以可以暴力枚举倍数更新。左端删除是 \(\mathcal O(1)\) 的。
考虑右端插入操作,比较暴力的是枚举其所有约数,对于每一个再枚举约数更新,记 \(d(x)\) 为 \(d\) 的约数个数,这样子单次复杂度是 \(\sum_{i|x}d(i)\) 的。
对于右端删除操作,我的做法是记录每一个开头位置的最优答案的最左边的位置,如果一次删除使得其最左边位置改变了就暴力枚举倍数删除,这样子最坏复杂度是单次 \(d(x)^2\) 的,我不太会卡。
\(\text{vector}\) 被卡常数卡飞了,改成边表以后貌似还蛮快的。
【清华集训2017】避难所
玄学题,不知道该怎么讲,每一步都是玄学,乱搞发现 \(n\) 较大的时候一定存在 \(iii\) 型的解,否则如果有解一定是 \(ijj\) 型的解,然后找 \(iii\) 解的时候倒着枚举加一些剪枝就过了。
【清华集训2017】榕树之心
先判断最后能否到 \(1\) 怎么做,考虑每一个节点不同儿子子树的两次操作会相互抵消,显然移回当前节点剩下最少操作的方案一定是剩下若干来自最大儿子子树的点,那么只需要尽可能消除最大儿子子树即可。
令 \(tot[u]\) 表示从 \(u\) 子树内从 \(u\) 出发最后回到 \(u\) ,最少剩余的生长操作数量。
其中 \(v\) 是 \(u\) 的所有儿子中子树大小最大的那个,考虑如果最大儿子内部消完剩下的东西可以直接用其它儿子的子树消掉,那么答案就是 \(sz[u] \bmod 2\) ,否则每一个其它儿子子树内的点都能和最大儿子剩下的东西消一下,直接减即可。
考虑一次性要求所有点的可行性怎么做,考虑在移到 \(u\) 时当前已经完成的操作一定是 \(1-u\) 的路径以及路径上挂着的一些子树,事实上一定存在一种策略可以让这些挂着的子树互相消除,那么问题就转化成和判断 \(1\) 的可行性类似的问题,把 \(1-x\) 路压缩起来当做新根即可。
【清华集训2017】某位歌姬的故事
首先对于覆盖一个位置的所有限制,只需要取最小的那个即可,然后所有限制的位置都不交了,分别计算方案数相乘即可。
那么问题就转化为若干个位置可以放黑白两种颜色的球,要求每一个限制区间里面必须有一个黑球,求方案数。其中一个白球有 \(m_i-1\) 种方案。
假设对第 \(k\) 种限制计算,令 \(dp(i,j)\) 为前 \(i\) 个位置最后一个黑球放在 \(j\) 的方案数,维护一下每一个位置对应的限制最左边的黑球可以放在哪里,记为 \(lim[i]\) 。