2022.4

四月了啊...

推一首歌吧 当时小椿沿海边跑的时候的 BGM,经典青梅竹马打不过天降妹子

反正在家网课,就顺便停课了

改的都是简单题,难题都弃了

好菜啊

好像没有那种花一下午时间研究一个算法的耐心了

ε-(´∀`; )

4.1

T1

不算太难,不写了

T2

给你一个 \(n\) 个点的无向图,计数满足 \(K\) 个限制的生成树数量,每个限制是一个点集 \(S_i\),要求 \(S_i\) 在生成树上的导出子图联通。

\(n\leq 500,K\leq 2000\)

生成树计数肯定是矩阵树定理。

考虑每一个限制 \(S_i\)\(S_i\) 的导出子图的边数 \(cnt_i\leq |S_i|-1\),且该限制被满足当且仅当取到等号。

我们考虑给原图每条边 \((i,j)\) 赋上边权 \(w(i,j)\)\(w(i,j)\) 为同时包含 \(i\)\(j\) 的限制个数,我们发现这样,对于它的生成树 \(T\),边权和 \(w(T)=\sum cnt_i\leq\sum(|S_i|-1)\),等号取到当且仅当所有限制都被满足,所以满足条件的生成树就是最大生成树。

最大生成树就是经典做法了,忘了的话去看一眼 Luogu P4208 [JSOI2008]最小生成树计数

还有 \(w(i,j)\) 的计算用 bitset 优化一下就是 \(O(\dfrac{n^2K}{\omega})\)

总复杂度 \(O(n^3+\dfrac{n^2K}{\omega})\)

T3

答案文件 10.1 K

长度为 \(n\) 的序列 \(a\),你有从中选出 \(k\) 个区间,区间的权值定义为所包含数的和。要求 \(k\) 个区间能覆盖整个序列,并且权值和最大,求最大权值和。

\(n\leq 10^5,k\leq \dfrac{n(n+1)}{2},|a_i|\leq5\times10^4\)

首先是一些 key observation

若两个区间为包含关系,那么我们显然可以舍弃被包含的区间,然后选择当前未选择的区间中权值最大的。因为最多 \(n\) 个不包含的区间就可以覆盖整个序列,所以前 \(\max(0,k-n)\) 大的区间一定被选

进一步观察,假设最优解选择了前 \(x\) 大的区间 \((\max(0,k-n)\leq x\leq k)\),此时剩下 \(m\) 个点没有被覆盖,那么剩下的 \(k-x\) 个区间一定两两不相交,并且每个区间至少覆盖 \(m\) 个未覆盖点中的一个。因为,若两个区间 \([l_1,r_1],[l_2,r_2]\) 相交,我们显然可以选 \([l_1,r_2]\) 代替,再选择当前未选择的区间中权值最大的,一定不劣。

所以我们先选上前 \(\max(0,k-n)\) 大的区间,计算它们的权值和以及它们覆盖的位置,然后再找到第 \(\max(0,k-n)+1\) 到第 \(k\) 大的区间。这个可以二分权值,然后再用树状数组,set 之类的东西求大于等于当前二分权值的区间个数,覆盖位置,权值和等等,这部分复杂度就是 \(O(n\log n\log V)\),但若干区间权值相同的情况真的是及其恶心。

然后我们逐个加入第 \(\max(0,k-n)+1\) 到第 \(k\) 大的区间,设当前未被覆盖的位置是 \(p_1,p_2,\dots,p_m\),我们需要对每个 \(1\leq i<m\) 求出 \(\max_{j=p_i}^{p_{i+1}-1}s_j-\min_{j=p_i}^{p_{i+1}-1}s_j\)\(s\)\(a\) 的前缀和),然后把这些值塞进 set 里,每次求出前 \(k-x-1\) 大的数的和,再加上 \(\max_{j=p_m}^ns_j-\min_{j=0}^{p_1-1}s_j\) 就相当于选出了 \(k-x\) 个区间覆盖了所有未覆盖点。随着 \(x\) 增大,会有一些 \(p_i\) 被删除,所以要动态维护那个 \(\max s_j-\min s_j\) 的值(插入,删除,查询前 \(k-x-1\) 大的数的和),搞一个 set 之类的数据结构就可以做了,这部分是 \(O(n\log n)\) 的。

据说还有 wqs 二分 + 线段树维护 DP 的做法,不太会...好像只有我写的题解做法还写了 10K

/tuu/tuu/tuu

4.2

T1

给你长度为 \(n\) 的字符串 \(S\) 和正整数 \(k\),判断 \(S\) 的每个前缀是否形如 \((AB)^KA\)\(A,B\) 可以为空串。

\(n\leq10^6\)

没一眼切是不是应该去死

枚举 \(i\),判断 \(S[1 .. i]\) 是否能作为 \(AB\),所以只需求 \(\operatorname{lcp}(S[1 ..n],S[i+1 .. n])\)

后缀数组,哈希都可以,新学了一下 Z 函数,这样就可以 \(O(n)\)

周三没有模拟赛,复习一下字符串,写个字符串总结(flag

T2

这个是原题 CF1120D 加了一个求方案数,(其实上一题也是原题 CF526D)

所以就不写了

有 DP 做法,也有最小生成树做法(能不能求方案数?)(去看题解)

T3

ARC016D

这个二分很有意思的欸

题意很长不写了,总是是求期望,也容易列出状态转移方程

\[f_{x,j}=\min\{f_{1,H}+H-j,1+\mathbb{E}_{(x,y)\in E}(f_{y,j-d_y})\} \]

边界

\[f_{x,j}=\infty\ (j\leq0)\\ f_{n,j}=0\ (j>0) \]

但这个是有后效性的,不过后效性只与 \(f_{1,H}\) 有关,我们考虑钦定 \(f_{1,H}=A\),然后直接按方程转移,最后在看算出的实际 \(f_{1,H}\) 是否等于 \(A\)

我们把这样计算出来的 \(f_{1,H}\) 看成是 \(A\) 的函数 \(f(A)\),想一想就有 \(f^\prime(A)\leq1\),所以就有 \([f(A)-A]^\prime\leq 0\) 他是有单调性的,可以二分出 \(f(A)=A\)\(A\),也就是答案。

至于这个 \(f^\prime(A)\leq 1\) 应该也可以感性证明,考虑按拓扑序归纳,考虑 \(A\) 减小了 \(\mathrm{d}A\)\(f_{n,\star}\) 不会变所以它的导数是 \(0\leq1\)\(f_{x,j}\) 如果从 \(A+H-j\) 转移来那么 \(\mathrm{d}f_{x,j}=\mathrm{d}A\),如果从 \(f_{y,\star}\) 转移来,那么 \(\mathrm{d}f_{x,j}=\mathrm{d}f_{y,\star}\leq \mathrm{d}A\) 也是成立的,所以就证明了恒有 \(\mathrm{d}f_{\star,\star}/\mathrm{d}A\leq1\)

4.4

T1 水题,T2交互

T2

猜树题,你要猜一颗二叉搜索树(按编号),可以 query(x,l,r) 询问 \(x\) 的子树是否恰好包含 \([l,r]\) 的点,询问次数是 \(2n\)

想到单调栈求笛卡尔树的做法,我们也考虑使用单调栈。

按标号顺序依次加点,栈中维护一条最右链,发现是可以一次询问出当前点是否在栈顶节点的右子树。

总之要想到单调栈。

T3

你要构造一个 \(n\) 个点的简单图,每个点的度数至少为 \(k\),且图中所有度数为 \(k\) 的点不能相邻,最小化边数。

\(2\leq k\leq10,2k+1\leq n\leq 1000\)

并不是构造题,因为重点在于求最小边数。

我们把点按度数等于 \(k\) 和大于 \(k\) 分类,设等于 \(k\) 的集合大小为 \(x\),那么两部分之间有 \(kx\) 条边,等于 \(k\) 的点之间不能连边,大于 \(k\) 的点之间可以连边,设连了 \(y\) 条。

容易列出不等式 \(kx+2y\geq(n-x)(k+1)\),为了 \(y\) 最小,解出 \(y=\min\left\{\left\lceil\frac{1}{2}[(k+1)n-(2k+1)x]\right\rceil,0\right\}\)。那么总边数 \(kx+y\) 就等于 \(\min\left\{\left\lceil\frac{1}{2}[(k+1)n-x]\right\rceil,kx\right\}\)\(x\)\(\lfloor\frac{(k+1)n}{2k+1}\rfloor\)\(\lceil\frac{(k+1)n}{2k+1}\rceil\) 时取得最小值。

得到了 \(x,y\) 之后构造方案就很简单了。

4.5

T1

给你一棵树,然后三个操作:

  • 向集合中加入一个数
  • 删除集合中的一个数
  • 询问集合中 \([l,r]\) 的数编号的节点到 \(x\) 的最小距离

\(n\leq 10^5\),强制在线。

很显然的点分树,对每个点用线段树维护它点分树上的后代即可。复杂度 \(O(n\log^2n)\)

T2

the same as 4.2 T3

T3

经过一个经典的卡特兰数模型 \((f_i=\sum_{j=0}^{i-1}f_jf_{i-j-1})\),问题转化成了求 \(\max_{i=l}^rv_7[(2i)!/(i!i!)]\),其中 \(v_p[x]\) 表示 \(x\) 的质因数分解中 \(p\) 的次数。

\(l,r\leq10^{10^4}\)

首先有

\[v_7[(2n)!/(n!n!)]=\sum\limits_{i\geq1}\left(\left\lfloor\dfrac{2n}{7^i}\right\rfloor-2\left\lfloor\dfrac{n}{7^i}\right\rfloor\right)=\sum_{i\geq1}\left[\left\lfloor\dfrac{2n}{7^i}\right\rfloor\bmod 2=1\right] \]

进一步考虑什么时候才是奇数,我们发现当且仅当对于一个 \(i\),存在 \(k\) 使得 \(n\in[k\times7^i-(7^i-1)/2,k\times7^i-1]\),所以我们把 \(l,r\) 转成 \(7\) 进制从高往低逐位考虑即可。

复杂度瓶颈是进制转化,所以是 \(O(\log^2r)\) 的。

好困,,所以写的好像很简略。

今天还行,三道题都是自己想的,不过赛时摸的有点多,就写了一道。

这几天题也不太难,天天都是一车 AK,不过跟我垫底关系不大。

4.7

T1

抽象出题意就是,给你一个长 \(n\) 的 01 序列,你可以进行 \(m\) 次操作,每次选择一个长 \(l\) 的区间全部赋成 \(0\),求操作后最少剩下几个 \(1\)

\(n,m,l\leq 10^6\)

不要想贪心了,不要想贪心了,不要想贪心了,虽然看上去很对但它就是错的。

先考虑一个看上去没什么前途的 dp,\(f_{i,j}\) 表示前 \(i\) 个数,进行了 \(j\) 次操作,最少的剩下 \(1\) 的个数。

转移很简单:\(f_{i,j}=\min\{f_{i-1,j}+[a_i=1],f_{i-l,j-1}\}\),时间复杂度 \(O(n^2)\)

关于这种有限制次数的问题,如果不限制次数,很容易求解最优方案,就要想到 wqs 二分

答案的凸性容易证明,所以通过 wqs 二分就做到了 \(O(n\log n)\)

T2

给你一个平面图,每次操作修改边权,你需要回答每次修改后的最小生成树,强制在线。

\(n,q\leq 10^5\)

首先肯定想到 LCT,如果是边权只能变小就非常容易了,但我们无法在一条树边变大后快速判断它还在不在生成树上。如果可以离线,可以通过线段树分治等做到 \(O(n\log^2 n)\),但即使这样,巨大的常数也是很难通过的。

考虑本题的特殊条件,实际上,平面图的最小生成树有下面的结论:

这真是太妙了,看完题解激动了好长时间。

平面图的最小生成树的补集是其对偶图的最大生成树

证明是容易的,把边集分成两部分后,平面图和对偶图两者任一个不连通当且仅当另一个中存在环,所以当两者都联通且不存在环(也就是在平面图和对偶图中分别形成一颗树),边数加起来恰好是 \(V-1+F-1=E\)

对于本题,我们用两个 LCT 分别维护原图和对偶图的最小生成树和最大生成树,改变一个边权时,如果是变小,用原图的 LCT 判断生成树是否改变,如果变大,用对偶图的 LCT 判断。

时间复杂度 \(O(n\log n)\)

T3

题意就是一个矩阵树定理,它的基尔霍夫矩阵(的 \(n-1\) 阶主子式)是长这样的(\(w\) 是给定的权值,\(S=\sum_{i=1}^{n-1} w_i\)

\[K=\begin{bmatrix} S+1&-w_1&-w_2&\cdots&-w_{n-1}\\ -w_{n-1}& S+1&-w_1&\cdots&-w_{n-2}\\ \vdots&\vdots&\vdots&\ddots&\vdots\\ -w_1&-w_2&-w_3&\cdots&S-1 \end{bmatrix} \]

就是一个 \(n\times n\) 的矩阵,求 \(|K|\),不过 \(n\leq2^{20}\)。(但保证了 \(n\)\(2\) 的次幂)

但这是一个循环矩阵,所以我们给它右乘一个范德蒙德矩阵(我数学菜,不知道怎么想到的,但乘完真的好神奇啊)

\[V=\begin{bmatrix} 1&1&1&\cdots&1\\ 1&\omega_n&\omega_n^2&\cdots&\omega_n^{n-1}\\ \vdots&\vdots&\vdots&\ddots&\vdots\\ 1&\omega_n^{n-1}&\omega_n^{2(n-1)}&\cdots&\omega_n^{(n-1)(n-1)} \end{bmatrix} \]

其中 \(\omega_n\)\(n\) 次单位根。我们先令一个函数 \(f(x)=S+1-\sum_{i=1}^{n-1}w_ix^k\)。然后发现 \(KV\) 是长这样的

\[KV=\begin{bmatrix} f(1)&f(\omega_n)&f(\omega_n^2)&\cdots&f(\omega_n^{n-1})\\ f(1)&\omega_nf(\omega_n)&\omega_n^2f(\omega_n^2)&\cdots&\omega_{n}^{n-1}f(\omega_n^{n-1})\\ \vdots&\vdots&\vdots&\ddots&\vdots\\ f(1)&\omega_n^{n-1}f(\omega_n)&\omega_n^{2(n-1)}f(\omega_n^2)&\cdots&\omega_{n}^{(n-1)(n-1)}f(\omega_n^{n-1})\\ \end{bmatrix} \]

发现 \(KV\) 就是 \(V\) 在每列乘了 \(f(\omega_n^i)\),所以 \(|KV|=|V|\prod_{i=0}^{n-1}f(\omega_n^i)\),又因为 \(|KV|=|K||V|\),所以我们要求的 \(|K|\) 就等于 \(\prod_{i=0}^{n-1}f(\omega_n^i)\)

直接 DFT 求出所有 \(f(\omega_n^i)\) 即可,复杂度 \(O(n\log n)\),好耶!

4.8

模拟赛直接摆烂,听完讲题 T2 直接弃

T1

给你长度为 \(n\)01? 构成的串 \(|S|\)

\(01\) 串序列 \(t_1,t_2,t_3,\dots,t_n\) 的个数,要求:

  • \(|t_i|=i\)
  • \(t_{i-1}\)\(t_i\) 的子序列
  • \(t_n\)\(S\) 将每个 ? 替换成 01 得到

\(998244353\)\(n\leq 250000\)

先来牛逼的转化题意

先不考虑 ?,从 \(t_n\)\(t_1\) 就是把 \(S\) 每次删一个字符,不过如果两中删法得到的序列相同,那么算同一种方案,所以我们不妨钦定删 0 只能删连续一段 0 的最右面那个,删 1 只能删连续一段 1 的最左面那个,也就是说,相当于每次找到一个 01 然后删掉其中的 01(再序列开头补一个 0,结尾补一个 1)。这样计数就不会重。

我们再每个两个位置中间加上分隔符,比如 101 变成 0A1B0C1D1,每次选择其中⼀个 01 删除的时候, 我们也把分隔符删除。那么每个分割符被删除的时间就是一个 \(0\sim n\) 的排列,而 0 相当于它左面的分隔符先于右面被删,1 是右面先于左面。

0 换成 <1 换成 >,计数满足条件的排列,据说这是一个经典问题。

\(f_i\) 表示考虑到第 \(i\) 个位置的方案,然后枚举前面 > 的位置容斥:

\[f_i=\sum\limits_{0\leq j<i,s_j='>'}(-1)^{cnt_{i-1}-cnt_j}\dbinom{i}{j}f_j \]

稍微变形:

\[\dfrac{f_i}{i!}=(-1)^{cnt_{i-1}}\sum\limits_{0\leq j<i}\dfrac{1}{(i-j)!}\dfrac{f_j}{j!}(-1)^{cnt_j}[s_j='>'] \]

现在它看起来就非常的卷积,于是分治 FFT 即可。

至于 ? 就是把序列分成若干段,每段分别计算,最后乘个组合数合并就行了。

时间复杂度 \(O(n\log^2n)\)

T3

有一个 \(n\) 个节点的树,你要从中选出若干条长度为 \(k\) 的简单路径(两两边不能相交,点可以相交)。求最大权值和。

\(n\leq 2\times 10^5,k=3/4,-10^9\leq w_i\leq 10^9\)

首先肯定往 DP 方面想吧,\(f_{x,j}\ (0\leq j<k)\) 表示节点 \(x\) 的子树中,并且从 \(x\) 往下选了一条长度为 \(j\) 的链,的最大权值。答案就是 \(f_{1,0}\)

不过我们发现转移有些棘手,我们分别考虑 \(k=3\)\(k=4\)

\(k=3\) 时,如果 \(f_{x,j}\)\(j=0\) 我们就是要把 \(y\in son(x)\)\(f_{y,0}\)\(f_{y,1}\) 两两配对,然后剩下的选 \(f_{y,2}\)(当然也可以不选),如果 \(j>0\) 就是选一个 \(y\)\(f_{y,j-1}\) 转移上来,剩下同样这么配对。

配对的过程我们可以再搞个 DP,\(g_{i,j}\) 表示考虑到第 \(i\) 个儿子,当前选的 \(f_{y,0}\)\(f_{y,2}\) 的差值为 \(j\)。记录一下前缀和后缀的 dp 值即可。

\(k=4\) 的情况类似,就是 \(f_{y,0}\)\(f_{y,2}\) 配对,然后 \(f_{y,1}\) 之间也要两两配对,剩下的选 \(f_{y,3}\) 或不选。给 \(g\) 加一维 \(0/1\) 表示当先选的 \(f_{y,1}\) 的奇偶即可。

不过问题就是,这个 \(g\)\(j\) 这一维大小是 \(|son(x)|\),这将导致总复杂度变成 \(O(n^2)\)

但我们真的需要把这一维开到 \(|son(x)|\) 吗?

我们把 \(x\) 的所有儿子顺序随机打乱,我们发现最优转移的情况就相当于随机一个 \(+1\)\(-1\) 的序列,最后的和为 \(0\)而这个随机 \(+1,-1\) 序列的前缀和最大值是低于 \(O(\sqrt n)\)。(这个好像有神仙证了),这意味着我们把 \(g\)\(j\) 这维开到 \(O(\sqrt n)\) 算出正确答案的概率是及其大的。

于是,时间复杂度 \(O(n\sqrt n)\)

4.9

T1 诈骗题,这不好。

T3 摆烂不看了,反正也没人过(好像数据锅了

T2

计数 \(n\) 个点的有向图,满足:

  • 每个点的出度和入度都为 \(2\),且不存在重边
  • 对每个点 \(u\),存在至多一个 \(p_u\),不能连边 \(u\rightarrow p_u\)

\(n\leq 500\),模 \(998244353\)

就大力容斥呗 /cy

题意抽象一下就是,\(n\) 对数填到 \(n\) 对位置上,其中每个位置有不能填的数,每对位置上的数不能相同,的方案数,不过因为每对位置两个数没有顺序,最终答案要除掉 \(2^n\)

先容斥掉 \(p_u\) 不能填的限制,我们先求出一个系数 \(dp_{i,j}\) 表示序列中选出了 \(j\) 个位置填了对应的 \(p\),且有 \(j\) 个位置中有 \(k\) 个位置上的数只钦定了一次。记 \(cnt_{i}\) 表示 \(i\) 在序列 \(p\) 中出现的次数,容易得到 dp

\[dp_{i,j,k}=dp_{i-1,j,k}+2\times cnt_i\times dp_{i-1,j-1,k-1}+4\times\dbinom{cnt_i}{2}\times dp_{i-1,j-2,k} \]

然后,我们设 \(f(x,y,u,v)\) 表示 \(x\) 个单独的数,\(y\) 对数,放入 \(u\) 个单独位置,\(v\) 对位置的方案。那么最终答案就能写成

\[ans=\sum\limits_{j=0}^n(-1)^j\sum\limits_{k=0}^{j}dp_{j,k} f(k,\dfrac{2n-j-k}{2},j,n-j) \]

然后我们考虑求 \(f\),注意此时 \(f\)\(x\) 个单独位置依然是有限制的,不能填对应的 \(p\),否则填的数就和原来和它一对的位置的数相同了。所以继续容斥

\[f(x,y,u,v)=\sum\limits_{i=1}^x(-1)^i\dbinom{x}{i}g(x-i,y,u-i,v) \]

其中 \(g\)\(f\) 含义类似,只不过单独位置上没有了限制。此时求 \(g\) 就容易很多了,若 \(u>0\) 考虑枚举其中一个单独位置放了哪个数,有以下递推

\[g(x,y,u,v)=x\times g(x-1,y,u-1,v)+y\times g(x+1,y-1,u-1,v) \]

递推边界 \(u=0\),剩下的位置都是成对的,相邻两个位置不能填相同的数,与是继续……容斥。

\[g(x,y,u,v)=\sum\limits_{i=0}^y(-1)^i\dbinom{y}{i}\dbinom{v}{i}i!(2(y-i)+x)!\dfrac{1}{2^{y-i}} \]

然后我们就做完了,发现对于 \(f\)\(g\) 都有 \(x+2y=u+2v\),所以状态数都是 \(O(n^3)\) 的,按照上面的式子挨个算,总复杂度 \(O(n^3)\)

4.11

T1

新听说了一个东西,积和式,不过这个东西没法多项式时间求,好像不是很有用。

不过这个题给的矩阵是一个下海森堡阵,积和式和行列式一样是可以拉普拉斯展开的。所以不断按第一行展开,就容易得到 \(O(n^2)\) 递推求积和式和行列式的方法。

T2

\(W(n)=\sum\limits_{i=1}^k\varphi(p_1^{\alpha_1}\cdots p_{i-1}^{\alpha_{i-1}})\times p_i\times \sigma_1(p_{i+1}^{\alpha_{i+1}}\cdots p_{k}^{\alpha_{k}})\),其中 \(n=\sum\limits_{i=1}^kp_i^{\alpha_i}\)\(n\) 的质因数分解。

\(\sum\limits_{i=1}^n W(i)\)\(n\leq 10^{10}\)

首先这个数据范围看起来就非常 min25。

但是 \(W\) 不是积性函数欸!

再想想,我们有 \(W(p^{\alpha}\times n)=\varphi(p^{\alpha})\times W(n)+p\times \sigma_1(n)\)\(n>1\)\(n\) 中不包含质因子 \(p\))。

所以就魔改一下 min25 的第二步求 \(S\) 就能做了(要同时筛 \(W\)\(\sigma_1\) 的和)

T3

有数列 \(f_0=f_1=1,f_n=9f_{n-1}+12f_{n-2}\),然后给你 \(n,P,a,b,c,d\),求 \(\gcd(af_n+bf_{n+1},cf_n+df_{n+1})\bmod P\)\(T\) 组数据。

\(T\leq 10^5,0\leq a,b,c,d\leq 1000,P\leq 10^9+7,n\leq 10^9\)

首先记 \(g_n=\gcd(f_n,f_{n+1})\),找规律猜出结论,\(g_n=3^{\lfloor n/2\rfloor}\)

然后通过辗转相除将 \(d\) 消成 \(0\),现在 \(ans=\gcd(a^\prime f_n+b^\prime f_{n+1},c^\prime f_{n})\)

先求 \(G=\gcd(a^\prime f_n+b^\prime f_{n+1},f_n)=\gcd(b^\prime f_{n+1},f_n)=g_n\gcd(b^\prime,f_n/g_n)\)。为了求 \(\gcd(b^\prime,f_n/g_n)\),我们考虑求 \(f_n/g_n\) 在模 \(b^\prime\) 下的值,这个是容易矩阵快速幂做的。

现在 \(ans=G\times \gcd(\dfrac{a^\prime f_n+b^\prime f_{n+1}}{G},c^\prime)=G\times \gcd(\dfrac{a^\prime f_n/g_n+b^\prime f_{n+1}/g_n}{G/g_n},c^\prime)\)。提出来一个 \(g_n/G\) 变成 \(g_n\times \gcd(a^\prime f_n/g_n+b^\prime f_{n+1}/g_n,G/g_n\times c^\prime)\),跟上一步一样,计算 \(a^\prime f_n/g_n+b^\prime f_{n+1}/g_n\)\(G/g_n\times c^\prime\) 的值即可。

最终复杂度就是 \(O(T\log n)\)

4.12

T1

T2

维护一个集合 \(S\),支持一下两个操作:

  1. 插入一个数 \(w\)

  2. \([0,w]\) 中选择一个数 \(x\)\(S\) 中选择两个数 \(i,j\),最小化 \((i+x)\operatorname{xor} (j+x)\),求这个最小值。

\(n\leq5\times 10^5,w\leq 2^{40}\)

首先是经典结论,如果有 \(a<b<c\) ,则有 \(\min(a \operatorname{xor} b,b \operatorname{xor} c)\le a \operatorname{xor} c\)。证明考虑 \(a\)\(c\) 二进制下从高往低第一个不同的位即可。

所以我们发现,能作为答案的 \(i,j\) 一定是 \(S\) 中元素排序后相邻的数。然后我们再考虑什么样的 \(x\) 有可能作为答案,发现 \(x\) 作为答案的必要条件是:\(i+x\)(或 \(j+x\))是 \(i\)(或 \(j\))将二进制下为 \(0\) 的一位改成 \(1\),它后面全改成 \(0\) 得到的。这样的 \(x\) 只有 \(O(\log w)\) 个,于是能作为答案的 \(x,i,j\) 总共只有 \(O(n\log w)\) 对。

\(val_i\)\(x=i\) 时的最小答案,我们用 set 维护所有可能作为答案的二元组 \((x,val_x)\),且 set 中只保留 \(x_1<x_2\)\(val_{x1}>val_{x2}\) 的二元组(类似单调栈),这样就可以 \(O(\log n)\) 的在 set 中二分查询答案了。

复杂度 \(O(n\log n\log w)\)

T3

码了 8.1 K 的数据结构题,调代码十分心情愉快(斯德哥尔摩了属于是)

一张无向图,最开始图仅有一个 \(0\) 号节点。现在有 \(n\) 次操作,每次操作为以下 \(5\) 种之一(不妨假设每次操作前这张图的节点编号区间为 \([l,r]\)):

  1. 删去 \(l\) 号节点,并删去 \(l\) 号节点连接的所有边。

  2. 删去 \(r\) 号节点,并删去 \(r\) 号节点连接的所有边。

  3. 增加 \(l-1\) 号节点,并连接 \(\min\{k-1,r-l+1\}\) 条边,第 \(i\) 条边连接 \((l-1,l-1+i)\),边有边权。

  4. 增加 \(r+1\) 号节点,并连接 \(\min\{k-1,r-l+1\}\) 条边,第 \(i\) 条边连接 \((r+1,l+1-i)\),边有边权。

  5. 对当前图询问最小生成树的边权和。

\(n\leq 5\times 10^5,2\leq k\leq10\)

动态维护 MST 不是 LCT 吗,有删除?线段树分治好了,我会 \(O(nk\log^2 n)\) 暴力!很好,过了

正解的启发思路来源于一个部分分,前 \(k-1\) 次操作都是 \(4\),此后保证 \(l\leq 0,r\geq k-1\)

我们假设现在已经得到了 \([l,r]\) 的最小生成树,要加入点 \(l-1\),此时我们尝试加入边 \((l-1,l-1+i)\),只需知道 \(l-1\)\(l-1+i\) 路径上的最大值即可,也就是说,我们感兴趣的只是 \([l,l+k-1]\) 这些点两两路径上的最大值,于是我们把 \([l,l+k-1]\) 的点当做关键点,求出其在 \([l,r]\) 最小生成树上的虚树,虚树上的边权为其在原树上代表的路径的边权最大值,该虚树大小只有 \(O(k)\),但根据它我们完全可以求出加入 \(l-1\) 后的最小生成树!

于是我们得到了一下做法,左面加入一个点时,只维护此时 \([l,l+k-1]\cup[0,k-1]\) 在最小生成树上构成的虚树(加上 \([0,k-1]\) 是为了方便最后与右边的结果合并),考虑到有删除操作,把过程中得到的虚树全部用 \(O(nk)\) 的空间存下来即可。具体地,加入一个点以及其连接的 \(k-1\) 条边时,与原来的虚树上的所有边放到一起 kruskal 求出新的最小生成树,让后 dfs 求出新的虚树,这部分复杂度为 \(O(k\log k)\)。右边的同理,询问时,只需把 \([l,l+k-1]\cup[0,k-1]\) 的虚树和 \([0,k-1]\cup[r-k+1,r]\) 的虚树放到一起跑 kruskal 即可,这样总复杂 \(O(nk\log k)\),我们就做完了这个部分分。

再考虑正解,我们发现其与正解的差别就是正解需要考虑到当前 \([l,r]\) 长度可能小于 \(k\),且 \([l,r]\) 一直在变化不会一直包含 \([0,k-1]\),这个的解决方法却非常暴力,那就是定期重构。

设当前 \([L,R]\ (L-R+1=k)\) 为当前的中心区间,如果 \(r<R\)\(l>L\),我们就直接令 \([L,R]\) 变成当前 \([l,r]\) 的中间位置,然后重新计算加入 \([l,L-1]\)\([R+1,r]\) 点的那些虚树。下面分析复杂度。

考虑势能分析,定义势能 \(\phi=\max\{L-l,r-R\}\),插入操作回让 \(\phi+1\),而重构操作会令 \(\phi\) 减半,重构的复杂度为 \(O(\phi k\log k)\),那么总的复杂度不会超过 \(O(nk\log k)\)

还有就是如果当前 \(r-l+1<k\) 我们就直接 prim 暴力求解即可,复杂度是 \(O(k^2)\),所以最终的复杂度为 \(O(nk^2)\)。不过实际的运行时间瓶颈显然不在这里,而在常数巨大的每次构建虚树。


后半个月

posted @ 2022-04-02 00:17  iMya_nlgau  阅读(106)  评论(1编辑  收藏  举报