退役前的做题计划3.0

退役前的做题计划3

好久没有更过博了呢。

总不能一直这么咕下去吧。

那就写点最近做过的题的题解吧。

[UOJ450][集训队作业2018]复读机

给一个长为\(n\)的序列染色,每个位置可以染\(k\)中颜色中的一种,要求每种颜色的出现次数为\(d\)的倍数,求方案数模\(19491001\)

构造指数生成函数\(f(x)=\sum_{i=0}^n\frac{1}{i!}x^i[d|i]\),答案就是\(f^k(x)\)\(n\)次项系数乘上\(n!\)

根据单位根反演有\([d|i]=\frac{1}{d}\sum_{j=0}^{d-1}\omega_d^{ij}\),所以有\(f(x)=\sum_{i=0}^n\frac{1}{i!}x^i\frac{\sum_{j=0}^{d-1}\omega_d^{ij}}{d}=\frac{1}{d}\sum_{i=0}^{d-1}e^{x\omega_d^i}\)

那么\(f^k(x)=\frac{1}{d^k}(\sum_{i=0}^{d-1}e^{x\omega_d^i})^k\),大力二项式定理展开,枚举\(a_0,a_1...a_{d-1}\in[0,k],\sum_{i=0}^{d-1}a_i=k\),该部分贡献的答案为\(\frac{k!}{\prod_{i=0}^{d-1}a_i!}(\sum_{i=0}^{d-1}a_i\omega_d^i)^n\)

时间复杂度\(O(k^{d-1}\log n)\)

[BZOJ3328]PYXFIB

\(A=\begin{bmatrix}1&1\\1&0\end{bmatrix}\)为斐波那契数列的转移矩阵

\[\sum_{i=0}^n\binom niF_i[k|i]=\sum_{i=0}^n\binom{n}{i}F_i\sum_{j=0}^{k-1}\omega_k^{ij}=\sum_{j=0}^{k-1}\sum_{i=0}^n\binom ni(\omega_k^jA)^i=\sum_{j=0}^{k-1}(\omega_k^jA+I)^n\]

所以直接矩阵快速幂即可,复杂度\(O(k\log n)\)

[UOJ453][集训队作业2018]围绕着我们的圆环

如果做过原题的话会发现答案只与\(C\)的秩有关。现在需要考虑的就是线性基的动态删除问题。

对线性基中的每个向量维护它是由原本的那些向量组成的,删除向量\(x\)时先找到包含\(x\)的一个零向量,将其异或到其他所有包含\(x\)的向量上(不会改变数值,但是改变了向量组成)再直接删除即可。若不存在包含\(x\)的零向量,则删除\(x\)势必会导致秩减小,找到包含\(x\)的最低位向量,同样异或到其他所有包含\(x\)的向量上即可。复杂度\(O(\frac{n^3}{\omega})\)

[BZOJ3600]没有人的算术

建立以大小为关键字的重量平衡树,再按照中序遍历的顺序分别分配\([0,1]\)的权值,这样就可以实现\(O(1)\)比较两个数的大小。

考虑新插入一个数怎么处理。因为新插入一个数时,组成它的那两个数的大小已经比较好了,所以可以对每个数记一个pair表示它是由哪两个数组成的,前一个视作第一关键字后一个视作第二关键字比较即可。最后还需要用线段树维护一下区间最小值的位置。

[BZOJ3682]Phorni

后缀平衡树模板题。

考虑插入一个新的后缀时,比它少一个字符的那个后缀已经比较过了。所以可以把当前位字符作为第一关键字,下一位后缀的大小作为第二关键字比较。同样需要用一棵线段树维护一下询问的答案。

[BZOJ4768]2555加强版之wxh loves substring

建立后缀平衡树,查询串\(s\)时,只需要查有多少后缀字典序小于\(s\),有多少后缀字典序小于\(s+\)一极大字符,两者答案相减即可。由于树高\(\log n\),所以可以暴力比较字典序,复杂度\(O(\sum |s|\log n)\)

[BZOJ5104]Fib数列

斐波那契数列的通项公式\(f_n=\frac{1}{\sqrt 5}[(\frac{1+\sqrt 5}{2})^n-(\frac{1-\sqrt 5}{2})^n]\),其中\(5\)在模\(10^9+9\)下存在二次剩余。简化一下问题,我们相当于需要求满足\(A^n-B^n=C\)的最小\(n\)值。

这个问题好像做不了,但是发现\(AB=-1\),所以就有\(A^n\pm\frac{1}{A^n}=C\)\(\pm\)是因为需要讨论\(n\)的奇偶性。

发现就是解一个二次方程,需要用二次剩余解出\(\sqrt{\Delta}\)从而解出\(A^n\),然后直接\(BSGS\)即可。

在这里写一下二次剩余的求法。规范一下,这里求\(x^2\equiv n\mod p\)的一个解\(x\),其中\(p\)是一个奇质数。

以下所有运算默认在模\(p\)意义下进行。

一个数\(n\)存在二次剩余的条件是\(n^{\frac{p-1}{2}}=1\)正确性显然。以下的两种做法都需要先判掉无解。

有一种\(O(\sqrt n)\)求二次剩余的方法,就是先求出\(p\)的原根\(g\),那么只需要用\(BSGS\)求出\(g^a=n\)\(a\),答案就是\(g^{\frac a2}\)

还有一种做法,先随机一个\(a\)使得\(a^2-n\)不存在二次剩余,这里的概率为\(\frac 12\)所以期望次数为\(2\)

定义\(\omega=\sqrt{a^2-n}\)

因为定义了\(a^2-n\)不存在二次剩余,因此\(\omega^{p-1}=(a^2-n)^{\frac{p-1}{2}}=-1\)

那么就会有\((a+\omega)^p=a-\omega\),证明可以根据二项式定理展开,会发现除了\(a^p\)\(\omega^p\)项外其余项都一定是\(p\)的倍数,又因为\(a^p= a\)\(\omega^p= -\omega\),故成立。

因为\((a+\omega)^{p+1}=(a+\omega)(a-\omega)=a^2-\omega^2=n\),所以我们就只需要求\((a+\omega)^{\frac{p+1}{2}}\)就是答案了。

现在证明一下\((a+\omega)^{\frac{p+1}{2}}\)中不含有\(\omega\)项。设\((a+\omega)^{\frac{p+1}{2}}=x+y\omega\),因为\((x+y\omega)^2=n\),所以\(x=0\)\(y=0\)

\(x=0\)时,\(y^2(a^2-n)=n\),由于\(a^2-n\)不存在二次剩余,\(y^2\)显然存在二次剩余,而\(n\)存在二次剩余,故矛盾。\(y=0\)得证。

[BZOJ3168][HEOI2013]钙铁锌硒维生素

矩阵乘法中\(A\times B=C\),可以发现\(C\)的列向量全部处于\(A\)的列向量所能够线性组成的空间里。所以只需要对于每个\(C\)的列向量求出参与组成它的\(A\)中列向量集合,然后做个二分图匹配即可。

上面要求的东西其实就是矩阵\(B\),所以直接矩阵求逆就行了。

求逆的方法也很简单,对\(C\)做线性变换使其变成单位矩阵,然后再用一个矩阵记录一下变换,这个记录变换的矩阵就是\(C\)的逆矩阵了。复杂度\(O(n^3)\)

题目要求二分图最小字典序匹配。倒着做是错的,原因是只保证了第一位的字典序最小而没有保证在第一位字典序最小的前提下第二位最小。正确的做法是先求出一组任意解,然后在从小到大依次确定匹配,标号大的点不能改动标号小的点的匹配。

[Luogu4707]重返现世

普通的\(\min-\max\)容斥的式子很简单,即\(\max_S=\sum_{T\subseteq S}(-1)^{|T|-1}\min_T\)

证明的话,只需要考虑第\(x\)大元素的被计算次数\(\sum_{i=1}^x(-1)^{i-1}\binom{x-1}{i-1}=(1-1)^{x-1}=[x=1]\)

现在考虑求\(kth\min-\max\)容斥,即求集合中第\(k\)大元素。

\(kth\max_S=\sum_{T\subseteq S}f(|T|)\min_T\)。我们现在需要求出容斥系数\(f(x)\)

根据定义,\(\sum_{i=1}^xf(i)\binom{x-1}{i-1}=[x=k]\)

二项式反演得\(f(x)=\sum_{i=1}^x(-1)^{x-i}\binom{x-1}{i-1}[i==k]=(-1)^{x-k}\binom{x-1}{k-1}\)

在这道题中枚举集合\(S\),显然\(\min_S=\frac{m}{\sum_{i\in S}p_i}\)。朴素\(dp\)的话直接记录\(f_{i,j,k}\)表示前\(i\)个数中选个\(j\)\(\sum p_i=k\)的方案数,复杂度\(O(n^2m)\)。注意到这里\(|n-k|\le10\),可以考虑组合数的递推式\(\binom nm=\binom{n-1}{m}+\binom{n-1}{m-1}\),分别计算出每个\(k'\in[1,k]\)的答案,可以做到\(O(nm(n-k))\)

[CF1096G]Lucky Tickets

不是直接构造生成函数求\(f^{\frac n2}(x)\)就行了?

注意\(998244353\)这个模数下\(NTT\)的最长有效长度是\(8388608\)

[BZOJ5219][Lydsy2017省队十连测]最长路径

求一张\(n\)点竞赛图从\(1\)号点出发能到达恰好\(i\)个点的边定向方案数。

一张竞赛图缩点后是一条拓扑序唯一的链。所以从\(1\)号点出发能够到达的点集就是\(1\)号点所在的强连通分量加上它后面的所有强连通分量。

\(g_i\)表示\(i\)点竞赛图的个数,显然\(g_i=2^{\binom i2}\)。设\(f_i\)表示\(i\)点强连通竞赛图的个数,枚举非强连通时拓扑序最小的强连通分量的大小,\(f_i=g_i-\sum_{j=1}^{i-1}\binom ijf_jg_{i,j}\)

求从\(1\)号点出发能到达恰好\(i\)个点的方案数,可以枚举\(1\)号点所在的强连通分量大小\(j\),贡献为\(\frac{(n-1)!}{(j-1)!(i-j)!(n-i)}f_jg_{i-j}g_{n-i}\)

以上的所有应该都可以做到\(O(n\log n)\)

[CF1096E]The Top Scorer

\(p\)个人,\(1\)号的分数至少是\(r\),所有人的总分数是\(s\),定义获胜的人是分数最高的所有人中等概率随机一个。求\(1\)号获胜的概率。\(p\le100, r\le s\le 5000\)

这个数据范围就很灵性,估计出题人就是想给\(O(p^2s)\)

\(O(s)\)枚举\(1\)号的实际分数,再\(O(p)\)枚举有多少人分数跟他一样高。现在问题就变成了把剩下的分数分配给剩下的人,每个人的分数不得超过\(k\)的方案数。枚举强制多少个人超过,xjb容斥一下就可以了,这里算一次的复杂度是\(O(p)\)。最后除以总方案数,就是把\(s-r\)个球放进\(p\)个盒子里的方案数。

其实可以把完整的式子写出来然后划一划之类的。在Codeforces上看到有人\(O(p)\)的做法过了。

[CF1096F]Inversion Expectation

给你不完整的排列,你会随机把这个排列补满,求期望逆序对数。\(n \le 2\times10^5\)

把产生的逆序对分为三类。

第一类是两个数都是你自己填的。记有\(s\)个位置不确定,那么\(\binom s2\)对每对产生的概率都是\(\frac12\),故贡献为\(\frac{s(s-1)}{4}\)

第二类是一个数是原来确定的一个数是你自己填的。先只考虑小的那个(下标靠后)是原来确定的而大的那个是你自己填的这个情况。枚举每一个确定的数,设它前面有\(x\)个可以填的位置,有\(y\)个可以填的数比它大,那么产生的贡献就是\(\frac{xy}{s}\)。另一种情况同理。

上面两类的计算都根据的是期望的线性性。期望的线性性指的是和的期望等于期望的和,即使拆分成的若干部分是相互关联的。

第三类是两个数都是原来确定的,直接树状数组统计就行了。

[Luogu4581][BJOI2014]想法

随机化。\(k\)\([0,m]\)的随机变量中,最小值的期望为\(\frac{m}{k+1}\)

对每个想法随机一个权值。对每道题求出它涉及到的想法中权值的最小值,就大致可以知道它涉及的想法的数量。每做一次复杂度\(O(n+m)\),多做几次差不多就行了。

[HDU5503]EarthCup

一种做法是暴力网络流,左边\(\binom n2\)个点流量为\(1\),右边\(n\)个点流量为\(a_i\),判断是否满流即可。

把第\(i\)个点拆成\(a_i\)个,相当于是问左右各\(\binom n2\)个点的二分图是否存在完美匹配。Hall定理。

\(a_i\)从大到小排序,记\(s_i\)表示前\(i\)大的\(a_i\)值之和,需要满足\(s_i \le \binom n2 - \binom {n-i}2\)

或者是将\(a_i\)从小到大排序,记\(s_i\)表示前\(i\)小的\(a_i\)值之和,需要满足\(s_i \ge \binom i2\)

两种做法显然是等价的。

[BZOJ3925][ZJOI2015]地震后的幻想乡

直观的想法是对于\(i\in[n-1,m]\)求出恰好在加入\(i\)条边后图连通的方案数再乘上\(\frac{i}{m+1}\)

把上面那个\(i\)乘到式子里面去,转化一下后会发现我们要求的东西变成了对于\(i\in[1,m]\)求出在加入至少\(i\)条边后图连通的概率。这个东西等价于加入恰好\(i\)条边后图不连通的概率。接下来的内容就完全和权值没有关系了。

\(f_{s,i,0/1}\)表示选出点集\(s\)的导出子图中的\(i\)条边,\(s\)这个集合连通/不连通的概率。转移只需要固定一个点,枚举它所在的连通块就行了。复杂度大概是\(O(3^nm^2)\)的。

[BZOJ3142][HNOI2013]数列

要求的东西是

\[\sum_{i_1=1}^m\sum_{i_2=1}^m...\sum_{i_{k-1}=1}^m(n-\sum_{j=1}^{k-1}i_j)\]

拆开分别算。前一项就是\(n\times m^{k-1}\),后一项可以考虑某一个\(i_j\),算出来是\((k-1)\times\frac{m(m+1)}{2}\times m^{k-2}\)

[UOJ384][HNOI2018]寻宝游戏

位运算中与\(1\)和或\(0\)两种操作是没有意义的,与\(0\)会强制变成\(0\),或\(1\)会强制变成\(1\)

如果最终结果某一位是\(0\),那么说明最后一次与\(0\)操作后没有或\(1\)操作,反之亦然。

\(m\)位每一位单独拿出来看,从后往前可以写成一个长为\(n\)的二进制串。把操作符按照与\(\to1\),或\(\to0\)的方式也转成一个长为\(n\)的二进制串,会发现最终结果的某一位为\(0\),当且仅当操作符对应的二进制串的字典序大于等于这一位上的二进制串的字典序,反之亦然。

所以直接排个序就行了。因为串的倒着输入的,所以可以直接使用基数排序。

[CF1097D]Makoto and a Blackboard

\(n=\prod p_i^{\alpha_i}\),根据乘法分配律,我们只需要求出每个\(p_i^{\alpha_i}\)最终期望变成多少就行了。

先忽略\(p_i\)只考虑指数,问题转化为了给一个数\(\alpha_i\),每次可以把当前的数\(x\)变成\([0,x]\)内的随机一个数,求\(k\)次操作后最终剩下\([0,\alpha_i]\)每个数的概率。

直接\(O(k\alpha_i^2)\)\(dp\)就行了。\(k\)再出大一点可以矩乘,因为\(\alpha_i\)不可能很大。如果硬是很大的话可以去参考Codeforces947E

猜你喜欢

转载自www.cnblogs.com/zhoushuyu/p/10271292.html
今日推荐