Loading

【题解】UOJ Long Round #1

// created on 22.09.22

A. 多线程计算

我们首先注意到:考虑给每个位置确定一个排名,那么排名之间的空隙大小期望是 \(\frac{1}{n\times m+1}\) 的。

\(f_{k,i,j}\) 表示插入排名前 \(k\) 的位置,恰好有 \(i\)\(j\) 列填满的方案数:

\[f_{k,i,j}=k!(nm-k)!\sum_{i'\geq i}\sum_{j'\geq j}{n\choose i'}{m\choose j'}{i'\choose i}{j'\choose j}(-1)^{i'-i+j'-j}{nm-i'm-j'n+i'j'\choose k-i'm-j'n+i'j'} \]

其中 \(k!(nm-k)!\) 是关于 \(k\) 的常系数。如果我们设计 \(g_{i,j}\) 表示至少有 \(i\)\(j\) 列填满的贡献和,同时令 \(f_{i,j}\) 也为贡献和,那么 \(f_{i,j}\) 可以通过 NTT 优化从 \(g_{i,j}\) 带上容斥系数求得,而 \(g_{i,j}\)

\[\begin{aligned} g_{i,j}&={n\choose i}{m\choose j}\sum_k F_kk!(nm-k)!{nm-im-jn+ij\choose k-im-jn+ij}\\ \end{aligned} \]

发现是卷积的形式:第 \(k-im-jn+ij\) 项和第 \(k\) 项组合,得到第 \(im+jn-ij\) 项。对于 \(im+jn-ij\) 相等的 \((i,j)\) 贡献是不变的。于是只需要 NTT 求 \(g_{i,j}\),关于容斥系数,只需要两维依次考虑即可。

远古提交记录:Submission #449630 - Universal Online Judge (uoj.ac)

B. 光伏元件

首先对于 \(C_{i,j}=-1\) 的相当于代价 \(+\infty\) 。我们将所有 \(A_{i,j}\) 翻转过来,并同时反转 \(C_{i,j}\),使得初始局面是全 \(0\) 的。接着设 \(x_{i,j}\) 表示 \((i,j)\) 最终的状态,我们有:

\[\min \sum_{i,j}x_{i,j}C_{i,j}\\ \forall i\in[1,n],\sum_{j}x_{i,j}\geq dl_{i}\\ \forall i\in[1,n],\sum_{j}-x_{i,j}\geq -dr_{i}\\ \forall j\in[1,n],\sum_{i}x_{i,j}\geq dl_{j}\\ \forall j\in[1,n],\sum_{i}-x_{i,j}\geq -dr_{j}\\ \forall i\in[1,n],\sum_{j}x_{i,j}-\sum_{i}x_{i,j}\geq -k\\ \forall j\in[1,n],\sum_{i}x_{i,j}-\sum_{j}x_{i,j}\geq -k\\ \]

变量个数 \(n^2\),约束条数 \(6n\) 。和线性规划套路中的网络流模型不贴近。事实是,我们清楚地知道 \(x\in[0,1]\),为什么不直接设计网络流呢?

我们考虑 \(k=0\) 的情况,用循环流限制流量相等:对于 \((i,j)\) 从行 \(i\) 向列 \(j\) 连边。要求行 \(i\) 和列 \(i\) 的出入度一样,就从列 \(i\) 向行 \(i\) 连边,这条边的流量就是他们的 \(c\) 。求解最小费用循环流就行了。

对于一般情况,我们考虑:新建原汇,假设源汇到 \(i,i'\),以及 \(i'\rightarrow i\) 的流量分别为 \(a,b,x\),那么 \(i\) 的出流量为 \(x+a\),而 \(i'\) 的入流量为 \(x+b\) 。我们只需要令 \(a,b\in[0,k],x\in[l,r-k]\) 就可以组合出所有合法的流方式,并且对应的所有流都是合法的。当 \(r-l<k\) 时相当于没有 \(k\) 的限制,只需要限制一下 \(i,i'\) 的上下界就行。

提交记录:Submission #584607 - Universal Online Judge (uoj.ac)

总结一下,建图比较平凡,而关于流量限制,考虑我们的实际流量是什么,关于单点就用源汇限制,关于双点就建反边限制。总体仍然是围绕 "合法流函数满足任意点的出入度一样" 进行的。

C. 服务器调度

一个点到点集最远的肯定是点集直径端点,如果没有修改的话,只需要考虑直径端点将树分成了两个部分,而两个部分对应了 DFN 序列上的 \(O(1)\) 段区间。顺序扫描将所有点的答案求出即可。

到了 Subtask 4 我们只关心距离和,那么贡献可以通过 "到根距离之和减去重复路径长度" 计算 —— 前者很简单,而后者讨论每条边的贡献,也仅仅相当于在祖先链上求个和。每次更新点集直径就重新考虑贡献。

接下来考虑原问题,仍然讨论每条边的贡献,每次通过倍增找到直径中间的分界点,最后的问题可以化为给边打标记。此时发现查询时边的贡献可以拆成两部分,一部分是祖先链,一部分是子树内,两部分都可以通过链分治加线段树完成。

提交记录: Submission #584643 - Universal Online Judge (uoj.ac)

总结一下,我感觉这题没啥营养。
顺带一题,上述提交记录中第一次实现了 DFN 序上的 \(O(1)\) LCA —— 常数比欧拉序小。

D. 打击复读

本来觉得不太可能直接 SAM,于是想到是 SA,不过差一个地方一直不会,结果又发现是带修的。

那做个毛线,考虑翻转问题。然后建 SAM,答案为:

\[\left(\sum_{i\in \mathbf{endpos}_u}wl_i\right)\left(\sum_{i\in \mathbf{endpos}_u}S_{i-L_u+1}-S_{i-R_u}\right) \]

可以发现 \(i-L_u+1\)\(i-R_u\) 可以拆开算。对于 \(i-L_u+1\) 的话,如果建立反串的 SAM,就只需要定位 \(S[i-L_u+1,i]\),然后 \(\sum\limits_{i\in \mathbf{endpos}_u}S_{i-L_u+1}\) 就是 \(\sum\limits_{i\in \mathbf{endpos}'_u}S_{i}\)

于是问题变成了对所有的 \(S[i-L_u+1,i]\) 定位。串定位是简单的。

因为代码实现并不难,所以这里就不写了。

总结一下,这题其实很诈骗 .. 但是在一定的时间内没做出来,主要问题出在没注意带修,然后故意避开 SAM 去想 SA 。不过,如果按照常规思路思考一下 SAM,然后发现其修改的只是左权值,就可以发现修改和 SAM 的结构相性极佳,从而翻转一下串,一下就做完了。

E. 校验码

考虑将 \(i\) 写成 \(d_i^2t_i\)\(j\) 同理,有:

\[\begin{aligned} ans&=\sum_{t_i=1}^{n}\mu(t_i)^2\sum_{t_j=1}^{m}\mu(t_j)^2\sum_{d_i^2t_i\leq n}\sum_{d_j^2t_j\leq m}d_i^cd_j^c\gcd (t_i,t_j)^c\\ &=\sum_{t_i=1}^{n}\mu(t_i)^2\sum_{t_j=1}^{m}\mu(t_j)^2\gcd (t_i,t_j)^cS\left(\sqrt{\lfloor\frac{n}{t_i}\rfloor}\right)S\left(\sqrt{\lfloor\frac{m}{t_j}\rfloor}\right)\\ &=\sum_{d=1}^{n}d^c\sum_{s=1}^{\lfloor\frac{n}{d}\rfloor}\mu(s)\sum_{t_i=1}^{\lfloor\frac{n}{sd}\rfloor}\mu(t_isd)^2\sum_{t_j=1}^{\lfloor\frac{m}{sd}\rfloor}\mu(t_jsd)^2S\left(\sqrt{\lfloor\frac{\lfloor\frac{n}{sd}\rfloor}{t_i}\rfloor}\right)S\left(\sqrt{\lfloor\frac{\lfloor\frac{m}{sd}\rfloor}{t_j}\rfloor}\right)\\ &=\sum_{d=1}^{n}d^c\sum_{s=1}^{\lfloor\frac{n}{d}\rfloor}\mu(s)\mu(sd)^2\sum_{t_i=1}^{\lfloor\frac{n}{sd}\rfloor}\left([t_i\perp sd]\mu(t_i)^2\right)\sum_{t_j=1}^{\lfloor\frac{m}{sd}\rfloor}\left([t_j\perp sd]\mu(t_j)^2\right)S\left(\sqrt{\lfloor\frac{\lfloor\frac{n}{sd}\rfloor}{t_i}\rfloor}\right)S\left(\sqrt{\lfloor\frac{\lfloor\frac{m}{sd}\rfloor}{t_j}\rfloor}\right)\\ \end{aligned} \]

问题变成,对于 \(d\in[1,n]\) 求解:

\[\begin{aligned} f(d)&=\left(\sum_{t_i=1}^{\lfloor\frac{n}{d}\rfloor}\left([t_i\perp d]\mu(t_i)^2\right)S\left(\sqrt{\lfloor\frac{\lfloor\frac{n}{d}\rfloor}{t_i}\rfloor}\right)\right)\left(\sum_{t_j=1}^{\lfloor\frac{m}{d}\rfloor}\left([t_j\perp d]\mu(t_j)^2\right)S\left(\sqrt{\lfloor\frac{\lfloor\frac{m}{d}\rfloor}{t_j}\rfloor}\right)\right)\\ \end{aligned} \]

对每个 \(d\) Min25 算理论复杂度好像可行,但是我们完全没用到其他性质!

\(g(n,d)=\sum\limits_{i=1}^{n}\mu(id)^2S\left(\sqrt{\lfloor\frac{n}{i}\rfloor}\right)\),要求的就是 \(g(\lfloor\frac{m}{d}\rfloor,d)\) 。而对于 \(g(n,d)\) 来说有:

\[\begin{aligned} g(n,d)&=\sum\limits_{i=1}^{n}\mu(id)^2S\left(\sqrt{\lfloor\frac{n}{i}\rfloor}\right)\\ &=\mu(d)^2\sum_{s|d}\mu(s)\sum\limits_{i=1}^{n}\mu(i)^2[s|i]S\left(\sqrt{\lfloor\frac{n}{i}\rfloor}\right)\\ &=\mu(d)^2\sum_{s|d}\mu(s)\sum\limits_{i=1}^{\lfloor\frac{n}{s}\rfloor}\mu(is)^2S\left(\sqrt{\lfloor\frac{\lfloor\frac{n}{s}\rfloor}{i}\rfloor}\right)\\ &=\mu(d)^2\sum_{s|d}\mu(s)g\left(\lfloor\frac{n}{s}\rfloor,s\right)\\ \end{aligned} \]

在考虑递推的形式之前,先来考虑一下初值怎么求:即求 \(g(n,1)=\sum\limits_{i=1}^{n}\mu(i)^2S\left(\sqrt{\lfloor\frac{n}{i}\rfloor}\right)\) 。而在这个基础上需要处理 \(\mu(i)\) 的前缀和,对于这点易知 \(\sum\limits_{i=1}^{n}\mu(i)^2=\sum\limits_{i=1}^{\sqrt{n}}\mu(i)\lfloor\frac{n}{i^2}\rfloor\) 。回到原问题 \(g(n,1)\),最后用到的肯定形如 \(n=\lfloor\frac{m}{d}\rfloor\) 。在一定范围内预处理,剩下的范围整除分块即可。

接下来我们考虑 \(g(n,d)\) 的状态数,考虑预处理出所有 \(d\leq m^{\frac{1}{3}}\) 的状态,状态数并不是很多。对于剩下的 \(d>\frac{1}{3}\) 的情况,递推的层数很少。

附 1:对于 \(\sqrt{\lfloor\frac{n}{i}\rfloor}\) 的整除分块有:令 \(k=\sqrt{\lfloor\frac{n}{i}\rfloor}\),那么找到最大的 \(r\) 使得 \(\sqrt{\lfloor\frac{n}{r}\rfloor}\geq k\),也即 \(\lfloor\frac{n}{k^2}\rfloor\geq r\) 。对于 \(\lfloor\frac{n}{i^2}\rfloor\) 的整除分块有:令 \(k=\lfloor\frac{n}{i^2}\rfloor\),那么找到最大的 \(r\) 使得 \(\lfloor\frac{n}{r^2}\rfloor\geq k\),也即 \(\lfloor\frac{n}{k}\rfloor \geq r^2\)

附 2:具体实现的时候,\(g(n,d)\) 的实际状态数只有 \(3.6\times 10^7\) 级别,而主要瓶颈在 \(g(n,1)\) 而不在转移。因此只需要考虑 \(g(n,1)\) 的求法(如果硬求是 \(m^{\frac{5}{6}}\),只能过 80pts)。如果我们能对 \(m^{\frac{2}{3}}\) 范围内预处理,剩下的值只有 \(m^{\frac{1}{3}}\) 个,再整除分块就是 \(m^{\frac{2}{3}}\) 的了。

于是考虑 \(g(n,1)-g(n-1,1)=\sum\limits_{i=1}^{n}\mu(i)^2\left(S\left(\sqrt{\lfloor\frac{n}{i}\rfloor}\right)-S\left(\sqrt{\lfloor\frac{n-1}{i}\rfloor}\right)\right)\),只有在 \(\sqrt{\lfloor\frac{n}{i}\rfloor}\)\(\sqrt{\lfloor\frac{n-1}{i}\rfloor}\) 不同时才有效。这样的情况发生当且仅当 \(\lfloor\frac{n}{i}\rfloor\)\(d^2\)\(i|n\)

附 3:更优一步可以考虑预处理 \(g(n,d),nd\leq B\)\(B\) 是一个阈值。其中 \(g(n,d)=\sum\limits_{i=1}^{n}\mu(id)^2S\left(\sqrt{\lfloor\frac{n}{i}\rfloor}\right)\),仍然考虑到 \(g(n,d)-g(n-1,d)=\sum\limits_{i=1}^{n}\mu(id)^2\left(S\left(\sqrt{\lfloor\frac{n}{i}\rfloor}\right)-S\left(\sqrt{\lfloor\frac{n-1}{i}\rfloor}\right)\right)\),同样处理即可。这种递归计算的东西底层预处理点东西总是有好处的。

提交记录:Submission #584789 - Universal Online Judge (uoj.ac)

总结一下,前半部分拆贡献莫反都比较基础,后半部分在算 \(f(d)\) 的时候我没有得到好的做法。Sol 的做法是直接用 \(g(n,d)\) 表示出那个式子,然后根据后续变化发现子问题模型。接着大胆搜一下状态发现状态数远比想象的少,然后优化求 \(\mu(x)^2\) 前缀和,再在 \(g(n,d)\) 的底层用一种批量处理的方式进行提前处理。

关键点还是在于列 \(g(n,d)\) 发现子问题,然后搜状态。以后遇见这种两维的计算函数不要不敢列出来 .. 其实直接毛咕咕发现状态数大概就有可以松的痕迹,再搜一下验证一下就大功告成了。

F. 卫星基站建设

咕了。

posted @ 2022-09-23 11:29  Qiuly  阅读(105)  评论(0编辑  收藏  举报