2022.11.15 闲话

看到有些人手动循环展开,其实可以用预处理器直接循环展开 .

具体就是 #pragma unroll <num>,用法详见百度 .


今天的闲话主题是 BFS,真是越来越水了,回想一下第一篇闲话 Divisor Summatory Function 预处理优于 \(\Theta(n)\) 的那两个解法还挺有价值的,现在这个 BFS 都成 CSP-J 难度内容了 .

而且昨天 joke3579 写了个图论专题,全方面吊打我啊 .


APJ 指出题目名最好不要和 APJ 有关

\(n\) 个长度为 \(m\) 的 01 串,需要构造一个长度相同的 01 串,最大化该串和给出的串中不同位数之和 .

\(1\le n\le 10^6\)\(1\le m\le 10\) .

建一个有 \(2^m\) 个点的图,每个点都与和自身只有一位不同的点连一条长度为 \(1\) 的边,然后 BFS 跑最长路即可 .

时间复杂度 \(\Theta(n+2^m)\) .


ARC084B Small Multiple

\(f(x)\) 表示十进制下 \(x\) 的数位之和,给一个正整数 \(k\),求使得 \(f(x)\) 最小的 \(k\mid x\),只需输出 \(f(x)\) .

\(2\le k\le 10^5\) .

考虑所有正整数数都可以从 \(1\) 开始进行有限次乘 \(10\) 或者加 \(1\) 完成 .

要维护的是数位和,则一次乘 \(10\) 贡献 \(0\),一次加 \(1\) 贡献 \(1\) .

于是每个正整数当成一个点,乘 \(10\) 连边权为 \(0\) 的边,加一为边权为 \(1\) 的边,这样问题变成了最短路(合法性:显然因为最短路的最短性所以不能用 \(10\) 个加一顶替一个乘 \(10\)).

还有一个 \(k\) 的倍数的限制没管,观察可以发现把每个数都模 \(k\),然后算一下 \(1\)\(0\) 的最短路即可,这样其实点数就变成 \(k\) 了 .

于是可以 01BFS,时间复杂度是 \(\Theta(k)\) 的 .


ARC151E Keep Being Substring

给一个序列 \(\{a_n\}\) 和它的两个子串 \(\{x\},\{y\}\),每次可以在 \(\{x\}\) 的开头或末尾加或删一个数字,并且要满足任意时刻 \(\{x\}\)\(\{a\}\) 的非空子串,求把 \(\{x\}\) 变成 \(\{y\}\) 的最少次数。

\(1\le n\le 2\times 10^5\) .

找到 \(\{x\}\)\(\{y\}\) 的最长公共子串 \(\{S\}\),若 \(\{S\}\) 非空那么答案显然就是 \(p+q-2|S|\),就是将 \(\{x\}\) 先删到 \(\{S\}\) 再加回来 .

\(\{S\}\) 为空,贪心地考虑,则一定是把 \(\{x\}\) 删成只剩一个数然后用一些操作让它变成 \(\{y\}\) 的子串然后加回去 .

考虑对于所有 \(i\),连边 \(a_i\leftrightarrow a_{i+1}\),则问题变成 在 \(\{x\}\)\(\{y\}\) 中分别选两个点 \(u,v\),使它们之间的最短路最小,这个多源 01BFS 即可 .

做完了,时间复杂度 \(\Theta(n)\) .


我是仙人掌

给一个无向图,每次查询的时候给一堆二元组 \((x_i,y_i)\) .

求图中有多少个点 \(u\) 与至少一个这次询问给出的二元组 \((x_i,y_i)\) 满足 \(\operatorname{dist}(u,x_i)\leq y_i\)\(\operatorname{dist}\) 表示这两个点在图中的距离 .

如果不连通 \(\mathrm{dist} = +\infty\) .

\(1\leq n\leq 1000\)\(1\leq m,q \leq 10^5\)\(\sum a\leq2.1\times 10^6\) .

这题其实有点搞笑,和 BFS 没太大关系 .

首先 \(n\) 遍 BFS 求出全源最短路 .

然后我们就可以算出从每个点 \(i\) 出发,最短路恰好为 \(j\) 的点的集合,前缀或一遍就可以得到不大于 \(j\) 的集合(用 std :: bitset 存一下).

询问的时候直接 bitset 暴力并一下即可,时间复杂度 \(\displaystyle \Theta\left(n^2+nm+\left(n^3+n\sum a\right)/w\right)\)

posted @ 2022-11-15 11:34  Jijidawang  阅读(39)  评论(4编辑  收藏  举报
😅​