退役前的做题记录3.0
好久没有更过博了呢。
总不能一直这么咕下去吧。
那就写点最近做过的题的题解吧。
如果需要代码的话可以去OJ上翻或者直接私信我保证及时回复
[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]=\frac 1k\sum_{i=0}^n\binom{n}{i}F_i\sum_{j=0}^{k-1}\omega_k^{ij}=\frac 1k\sum_{j=0}^{k-1}\sum_{i=0}^n\binom ni(\omega_k^jA)^i=\frac 1k\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(别问我我不会)。
[CF1097F]Alex and a TV Show
对数组\(f\)定义莫比乌斯变换\(g_i=\sum_{i|j}f_j\)。这样一来集合加依然可以直接按位相加,集合乘也可以直接按位相乘。询问时对集合做逆莫比乌斯变换,因为\(-1\equiv1\mod 2\)所以并不用管\(\mu(i)\)的符号问题,只需要把非零位拿出来数\(1\)的个数就行了。注意这一步需要预处理否则复杂度可能会退化到\(O(7000m)\)。
用bitset维护集合,复杂度\(O(\frac{7000m}{\omega})\)。
[CF850F]Rainbow Balls
分别考虑每种颜色成为最终剩余颜色的概率。记\(S\)为球的总数。
设\(f_x\)表示当前有\(x\)个制定颜色的球,要求\(x\)在到达\(0\)之前到达\(S\)。可以列出方程:
\[f_x=pf_{x-1}+pf_{x+1}+(1-2p)f_x+\frac xS\]
其中\(p=\frac{x(S-x)}{S(S-1)}\)。
由于\(f_0\)不存在故\(f_1=pf_2+(1-2p)f_1+\frac 1S\),解得\(f_2=2f_1-1\)。
对\(f_x\)差分一下可得\(f_x-f_{x+1}=f_{x-1}-f_x+\frac{S-1}{S-x}\),故\(f_1=f_1-f_S=\sum_{i=2}^S(f_{i-1}-f_i)=(S-1)(f_1-f_2)+(S-1)(S-2)\),因此解得\(f_1=\frac{(S-1)^2}{S}\)。
代入递推即可。
[Wannafly挑战赛24D]无限手套
大力\(dp\)。设\(f_{i,j}\)表示前\(i\)种总共选了\(j\)个的总和,显然\(f_{i,j}=\sum_{k=0}^jf_{i-1,k}\times(a_i(j-k)^2+b_i(j-k)+1)\)。分别维护下\(j^2,j\)项系数以及常数项系数就能做到\(O(nm)\)了。
[Luogu4482][BJWC2018]Border 的四种求法
设当前询问为\([l,r]\),答案点为\(w\),那么就应该有\(l\le w
我们知道两个前缀的\(lcs\)是后缀树上两个节点的\(lca\)的深度,因此我们设\(t=lca(w,r)\)。上面的限制改为\(len_t\ge w-l+1\)。
对后缀树进行树链剖分。分两种情况讨论:\(t\)到\(r\)的第一条边是轻边,或者\(t\)到\(w\)的第一条边是轻边。两者可能有交集,但显然并不影响正确性。
若\(t\)到\(r\)的第一条边是轻边,那么从\(r\)出发跳重链就可以跳到\(t\)这个点。于是就只需要在\(t\)点的\(RIght\)集合里找\(\le\min(r-1,len_t+l-1)\)的最大的\(w\)就行了。线段树合并维护\(Right\)集合后线段树上二分即可。这一步的复杂度是\(O(n\log^2n)\)的,空间\(O(n\log n)\)。
若\(t\)到\(w\)的第一条边是轻边,仍然从\(r\)出发跳重链,假设跳到的点是\(x\),那么此时的\(t\)一定位于\(x\)所在的重链的前缀上,且\(w\)位于重链前缀上某个点的轻子树内。我们可以这样处理:先将询问点对\(x\)挂链,接着顺次考虑每条重链,用数据结构维护出这条重链所有轻儿子的\(w\),然后直接查询即可。因为加入\(w\)时\(t\)是已知的,所以要查询的\(w\)需要满足的仍是一个一维的限制。用线段树维护即可。复杂度\(O(n\log^2n)\),空间复杂度\(O(n)\)。
[LOJ2585][APIO2018]新家
首先把所有询问离线,按时间顺序处理。每家商店在\(a_i\)时刻插入,在\(b_i+1\)时刻删除,这样时间的影响就没有了。
对于一组询问,首先二分答案,问题转化成了问区间内是否所有颜色都出现过了。使用传统的区间数颜色方法\(O(q\log^3n)\)显然无法接受,考虑对每个位置维护其后继相同颜色的位置\(suf\),那么区间\([l,r]\)内出现了所有颜色,当且仅当\([0,l-1]\)内的\(suf\)的最大值不超过\(r\)。考虑到询问区间之前可能不存在某种颜色的情况,可以在数轴前方放每种颜色各一个,这样就可以直接维护前缀\(suf\)最大值了。复杂度\(O(n\log n+q\log^2n)\)。
[HDU3629]Convex
考虑四个点不构成凸多边形的情况,一定是一个点位于其他三个点围成的三角形内。我们先枚举一个点,然后考虑计算剩下的\(n-1\)个点围成的三角形中有多少个不包含这个点,这个可以极角排序后做到\(O(n)\),做法是枚举一个\(i\)作为三个点中极角最小的那个,并找到最大的\(j\)使\(i,j\)的极角相差不超过\(\pi\),这里便可以产生\(\binom{j-i}{2}\)的贡献。最终构成凸多边形的四点总共贡献了\(4\)的答案,不构成凸多边形的四点贡献了\(3\)的答案,所以再减去\(3\binom n4\)即可。
[BZOJ1913][Apio2010]signaling 信号覆盖
枚举一个圆,再枚举一个点,求这个点在圆内的概率。发现任意四个点若构成凸多边形则共产生\(2\)的答案,否则只产生\(1\)的答案。所以向上面那题一样算出四个点构成凸多边形的方案数即可。
[UOJ218][UNR #1]火车管理
用可持久化线段树维护所有栈,记录栈顶和以及压栈的时间戳。弹栈时只需要根据这个时间戳就能够找到压栈前栈顶的权值了。
[LOJ2729][JOISC 2016 Day 1]俄罗斯套娃
对偏序关系连单向边,那么题中所求的东西就是最小链覆盖。根据Dilworth定理,最小链覆盖等于最长反链长度,也就是一个类LIS状物。
询问离线,按高度顺序处理,每次操作为插入一个数或者查询一段后继的LIS长度。只需要用一个支持单点插入,后缀取最大值的数据结构即可。
[LOJ2831][JOISC 2018 Day 1]道路建设
LCT,每次把\(access\)途中经过的每一段颜色拿出来,用BIT求答案。复杂度\(O(n\log^2n)\)。
[UOJ291][ZJOI2017]树状数组
题目中树状数组的写法实际上是维护了后缀和。也就是说九条算出来的答案是\([l-1,r-1]\)的区间和。
于是我们就只需要求\(l-1\)位置与\(r\)位置被修改次数的奇偶性相同的概率就行了,注意\(l=1\)需特判。
不能直接计算\(l-1\)为奇数的概率\(\times r\)为偶数的概率\(+l-1\)为偶数的概率\(\times r\)为奇数的概率,因为一个同时包含了\(l-1\)与\(r\)的区间是只能修改一个值的。所以应该用一个二维数据结构维护区间,即左端点一维右端点一维,询问时二维数点即可。
[UOJ349][WC2018]即时战略
首先链的情况需要特判掉。将编号随机打乱后依次加入可以做到期望\(O(n+\log n)\)次询问。
LCT。每次新加入一个点时,从\(1\)号点出发开始询问,如果得到的点在当前重链上就在\(splay\)上二分找点,否则就需要切换重链。找到位置后\(link\)一下维护树的形态并执行\(access\)操作。
这个做法看上去很假但是我也不知道怎么它就过了。
[CF671D]Roads in Yusland
给一棵\(n\)点的树和\(m\)条直链(连接一个点与它的某个祖先),每条链有个权值\(c_i\),求选出一些链覆盖树上所有边且权值和最小。
这个问题可以转对偶做:给每条树边确定一个权值,要求每条链覆盖的所有树边的权值和不超过\(c_i\),最大化所有树边的权值和。可以自底向上贪心,每次选能选的最大权值,需要合并所有儿子的限制,可并堆即可。
[BZOJ5317][JSOI2018]部落战争
对两个点集分别求出凸包,设为\(A,B\),题意是给出一个向量\(t\),问是否存在\(a\in A,b\in B\)满足\(b+t=a\),移项可得\(a-b=t\),故构造\(A-B\)的闵可夫斯基和,然后判断点是否在凸包内即可。
[CodeChef - SADPAIRS]Chef and Sad Pairs
首先建圆方树,然后对每种颜色的点建立虚树。在虚树上出现了的点的答案可以直接统计,其余的贡献对于每条边是相同的,所以直接树上差分统计即可。
[CF671C]Ultimate Weirdness of an Array
考虑计算当\(f(l,r)\le i\)时,每个\(l\)对应的右端点\(r\)最左能取到哪里,记为\(next_l\)。初始时\(next_l=l\)。
从大到小枚举\(i\),考虑当限制从\(f(l,r)\le i\)变成\(f(l,r)后,哪些\(next_l\)会发生改变。取出所有是\(i\)的倍数的数的位置下标,记为\(x_1,x_2...x_m\),因为\(f(l,r)\)中至少要包含\(m-1\)个\(x_i\)(不然\(f(l,r)\)就至少是\(i\)了),所以\(l\in[x_2+1,n]\)内的\(next_l\)直接变成\(n+1\),\(l\in[x_1+1,x_2]\)的\(next_l\)对\(x_m\)取\(\max\),\(l\in[1,x_1]\)的\(next_l\)对\(x_{m-1}\)取\(\max\)。每次修改后统计\(\sum_{l=1}^nn+1-next_l\)就是满足\(f(l,r)\le i\)的区间数。
看上去需要\(O(n\log^2n)\)的吉利线段树,但实际上\(next_l\)是随下标单调的,所以取\(\max\)操作修改的一定是区间的一段前缀,直接暴力就好了。复杂度\(O(n\log n)\)。
[LOJ2978][THUSCH2017]杜老师
乘积为完全平方数就是要求每个质因子的出现次数为偶数。
对每个质因子的出现次数列个异或方程,相当于要求这个异或方程的解的个数。
把方程写成矩阵的形式,设这个矩阵的秩为\(r\),显然答案就是\(2^{R-L+1-r}\)。
所以我们需要求秩。
有一个结论是\(R-L+1\ge 6000\)时矩阵的秩就等于区间内包含的质数个数,也就是说每个质数的方程都是线性无关的。那么就只需要考虑\(R-L+1< 6000\)的情况了。
直接暴力高斯消元的话,质数个数可能会很多。但是由于每个数至多含有一个大于\(\sqrt R\)的质因子,所以我们对每个大于\(\sqrt R\)的质因子记录一下是否出现了,对所有小于等于\(\sqrt R\)的质因子进行高斯消元就行了。
[LOJ2977][THUSCH2017]巧克力
如果\(c_{i,j}\)很小,可以直接状压记录状态转移。转移就是裸的斯坦纳树。
现要求在最小化块数的前提下最小化中位数,可以二分中位数\(mid\),将\(a_{i,j}\)大于\(mid\)的位置设为\(M+1\),否则设为\(M-1\),其中\(M\)是一个较大的数。这样就可以在不影响块数的前提下二分得到最小的中位数。
还需要解决的一个问题是\(c_{i,j}\)可能很大。可以将每个\(c_{i,j}\)随机映射到\([1,k]\)内,当构成答案的\(k\)种数分别映射到\([1,k]\)的不同值时就一定可以求出正确答案。
[CodeChef - TREEWALK]Walk on Tree
有一个显然的\(O(n^3\log k)\)矩乘做法。
下一步没什么意思,直接\(BM\)就做到\(O(n^2\log k)\)了。
[LOJ2980][THUSCH2017]大魔法师
用矩阵表示线段树标记,用一个\(1\times4\)的行向量表示\(a,b,c\)值的和以及区间长度。六种操作对应的矩阵分别为:
\[\begin{bmatrix}1&0&0&0\\1&1&0&0\\0&0&1&0\\0&0&0&1\end{bmatrix},\begin{bmatrix}1&0&0&0\\0&1&0&0\\0&1&1&0\\0&0&0&1\end{bmatrix},\begin{bmatrix}1&0&1&0\\0&1&0&0\\0&0&1&0\\0&0&0&1\end{bmatrix},\begin{bmatrix}1&0&0&0\\0&1&0&0\\0&0&1&0\\v&0&0&1\end{bmatrix},\begin{bmatrix}1&0&0&0\\0&v&0&0\\0&0&1&0\\0&0&0&1\end{bmatrix},\begin{bmatrix}1&0&0&0\\0&1&0&0\\0&0&0&0\\0&0&v&1\end{bmatrix}\]
需要卡常。两个矩阵标记合并的时候如果一者为单位矩阵就直接赋值,此外多加一些“如果值为\(0\)就不转移”的判断就行了。
[LOJ2979][THUSCH2017]换桌
显然费用流。对所有人建\(nm\)个点,先给每一桌连成一个环,然后考虑跨桌的移动。建两棵线段树,一棵表示“向左走”一棵表示“向右走”,即分别向左/右子树走时产生代价。建出图后大概会有\(10k+\)的点数和\(90k+\)的边数,然而\(spfa\)费用流+多路增广就过了。
[LOJ2981][THUSCH2017]如果奇迹有颜色
首先根据\(polya\)定理有\(ans=\frac{\sum_{i=1}^nf(gcd(i,n))}{n}=\frac{\sum_{d|n}\varphi(\frac nd)f(d)}{n}\),其中\(f(n)\)表示长度为\(n\)的环保证任意相邻\(m\)个数不出现\(m\)种不同颜色的方案数。现在考虑求\(f(n)\)。
暴力\(dp\)复杂度\(O(m^{2m-1}n)\),因为总状态数为\(m^{m-1}\),需要枚举起点后暴力枚举所有状态,每个状态需要\(O(m)\)转移。可以矩乘优化到\(O(m^{3(m-1)}\log n)\)但是没有什么卵用。
直接暴力求出前若干项后\(BM\)即可。\(m=6\)开-Ofast
跑了大概\(17\min\),\(m=7\)还没跑出来。
update:算了一下要跑差不多两天。弃疗了,去\(loj\)上蒯了yww的递推式打出了\(n\le1000\)的表。
update2:最后一个点跑得有点慢,估计出题人的原意是想要选手打表?
[LOJ2732][JOISC 2016 Day 2]雇佣计划
连续段数等于边界数除以\(2\),这里的边界需要满足相邻两数一个\(\ge v\)一个\(
对于相邻的两个数\(a,b\),他们会使得位于\((a,b]\)的所有询问的答案加\(1\)。
所以树状数组xjb维护一下就行了。
[LOJ2838][JOISC 2018 Day 3]比太郎的聚会
需要求的信息非常不好维护。考虑根号分治。
发现\(\sum Y_i\le 10^5\),所以可以对询问的\(Y_i\)分治,令\(B=\sqrt{10^5}\),若\(Y_i,则对每个点维护到达它距离前\(B\)大的点集。否则这样的询问个数不超过\(B\),直接暴力\(dp\)一遍即可。
[LOJ2881][JOISC 2014 Day3]电压
先建出\(dfs\)树,这时候所有非树边都一定是返祖边。我们记\(0\)边表示连接两点在树上深度相差为偶数的非树边,\(1\)边表示连接两点在树上深度相差为奇数的非树边。
若需要使某条树边成为答案,必然是使这条树边连接的两端点染同色,然后剩下的点黑白染色(树是二分图啊)。这就需要这条边满足两个性质:不存在\(1\)边覆盖这条树边,且所有\(0\)边都覆盖这条边。树上差分一波即可解决。
若需要使某条非树边成为答案,发现当且仅当只有一条\(0\)边的时候,这条\(0\)边才有可能成为答案。这个特判一下就好了。
[UOJ193][UR #14]人类补完计划
发现要求的东西就是从原图中选出一棵基环树,贡献是\(2\)的基环树上非叶节点个数次方。我们假设现在已经求出了\(h_s\)表示\(s\)这个点集构成一棵基环树的方案数,由于不知道叶子节点的个数,我们考虑删除所有叶子节点,这样剩下的部分肯定还是一棵基环树。但是这样的方案可能会算重,所以需要容斥一下,那么\(s\)集合对答案的贡献就是\(ans_s=\sum_{t\subseteq s}(-1)^{|t|}h(s-t)2^{|s|-|t|}\)。
那么如何求\(h_s\)呢?首先我们可以求出点集\(s\)连成一个环的方案数,这个记个\(f_{i,j}\)表示从__builtin_ctz(i)
出发到\(j\),经过了点集\(i\)的方案数,枚举新加入那个点转移,要求新加入的点编号大于__builtin_ctz(i)
,当首尾可以相连时便计入答案。接着可以考虑在环上加入某个点集,每个点都是独立的所以转移系数是每个点向环上点连边方案数的乘积。由于同样会算重所以也需要容斥。
[UOJ192][UR #14]最强跳蚤
给每个质因子随机一个权值,求异或和为\(0\)的树上路径条数即可。
[UOJ186][UR #13]Yist
考虑每个需要被删除的数\(x\)。找到它左边第一个不需要被删除且比它小的数\(u\),右边第一个不需要被删除且比它小的数\(v\)(假设左右两侧分别有一个不需要被删除的\(0\)),那么删除\(x\)可行的最长区间长度是\(v-u-1-(u,v)\)中比\(x\)小的且要被删除的数,答案就是对每个要被删除的数的答案取\(\min\)。考虑优化这一过程,从大往小枚举\(x\),那么当某个\(x\)的区间与前一个\(x'\)的区间有交,则\(x\)的区间会完全包含\(x'\)的区间,从而使\(x\)的答案一定大于等于\(x'\)的答案,这样就可以直接continue
了。由于每个位置至多被访问到一次,所以复杂度线性。
[UOJ311][UNR #2]积劳成疾
}设\(f_{i,j}\)表示长度为\(i\)的区间最大值不超过\(j\)的所有方案的权值之和。转移时先从\(f_{i,j-1}\)转移过来,接着就枚举最大值第一次出现的位置,设为\(p\),那么此时就确定了\(\min(i,p+k-1)-\max(k,p)+1\)个长度为\(k\)的区间的最大值,因此\(f_{i,j}=f_{i,j-1}+\sum_{p=1}^iw_j^{\min(i,p+k-1)-\max(k,p)+1}f_{p-1,j-1}f_{i-p,j}\)。注意当\(i
[UOJ308][UNR #2]UOJ拯救计划
可以发现答案是\(\sum_{i=1}^kA_k^i\times\)选\(i\)种颜色给原图染色使得相邻点不同色的方案数。由于当\(i\ge 3\)时\(6|A_k^i\),所以就只需要考虑\(i=1,2\)的情况了。注意当不存在边的时候\(i=2\)的方案数应为\(2^n-2\)。
[UOJ74][UR #6]破解密码
显然\(s_i=\frac{26h_i-h_{i+1}}{26^n-1}\)。当\(26^n\equiv1\mod p\)时不能做除法,此时可以直接用\(h_0\)构造一个字符串,只要这个字符串对\(h_0\)合法它就一定对所有\(h_i\)都合法。
[UOJ75][UR #6]智商锁
生成树的方案可以划分为若干子集的生成树方案的乘积,只需要把这些子集连成一棵树即可。
随机\(1000\)张\(25\)个点的图,对每张图用基尔霍夫矩阵求出其生成树个数,设为\(f_i\),我们只需要找到四个数\(a,b,c,d\)使\(f_a\times f_b\times f_c\times f_d=k\)即可。双搜+哈希表即可。
至于这样为什么是对的......你可以认为所有的\(f_i\)都是在\([0,mod)\)之间随机分布的,这样就大概率能得到解?
[UOJ118][UR #8]赴京赶考
仔细yy一下后会发现两维是独立的,然后就做完了。
[UOJ119][UR #8]决战圆锥曲线
答案点不一定在凸壳上,但是满足存在\(j\)使得\(i
[UOJ91][集训队互测2015]最大异或和
先对原序列差分,这样不改变其能够线性组合出的向量集合。这样以来操作一就是两个单点修改,操作二是两个单点修改加上一段区间覆盖为\(0\)。由于一次修改操作至多让两个位置变成非\(0\),所以暴力覆盖成\(0\)的复杂度显然会是对的。
接下来就是动态线性基的问题了。这篇题解里面的第三道题有讲。
[UOJ168][UR #11]元旦老人与丛林
先瞎猜一个结论:答案为Yes
当且仅当对于任意点集\(V\),其导出子图的边集\(E\)满足\(|E|\le2|V|-2\)。
所以就只需要检验是否存在一个点集\(V\)与其导出子图的边集\(E\)满足\(|E|>2|V|-2\)就行了。转化成最大权闭合子图的模型,点的权值为\(-2\),边的权值为\(1\),求最大权非空闭合子图的权值是否大于\(-2\)即可。
但是当最大权非空闭合子图的权值小于\(0\)时我们求出的答案一定会是\(0\),所以需要强制选后一个点使其权值为\(0\),然后判断最大权闭合子图的权值是否大于\(0\)即可。
看上去需要跑\(n\)次网络流,但实际上每次就只有一条流量为\(2\)的边发生了改变,所以直接退流即可。