梦熊 2025 省选集训营 做题笔记

· · 算法·理论

20250204 模拟 T1

删点 MST,3\leq n,m\leq 5\times 10^5

Sub 1

暴力模拟。或者写正解没上数据结构优化。 ## Sub 2 数据随机。哈哈我也不会。 赛时没几个人会的档。由于随机所以造出来的树每个点度数都不多,暴力维护连通块。没写,大概就这个意思。 ## Sub 3 一条链 $(i,i+1,1)$ 然后后面随便连点边。 MST 一定是这条链。 一次只会分成两个连通块。就是求 $u\lt i\lt v$ 的最小边权。 扫描线一下。 ## 赛时提交记录 <https://mna.wang/contest/submission/765776> ## 正解 前言:删边 MST 版本。 <https://atcoder.jp/contests/JAG2013Spring/tasks/icpc2013spring_e> <https://codeforces.com/problemset/problem/827/D> <https://codeforces.com/problemset/problem/1184/E3> 我因为做过然后一时半会儿没转过弯来调了一个多小时倒闭了。GGG。 场上的时候我先是注意到了增量是 $\mathcal O(n)$ 的,一直在想处理每条边对应的可替代边,然后去重,掐头掐尾。 写了一下这个的暴力版本过不去拍但是过了大样例的第一个。我想先把这个改对了再套树剖,没测别的大样例。一直挂,寄寄寄。这个看起来可能有点对但是不太靠谱。 这个做法的主要思路和 std 都差不多。唯一问题好像是,我不能很方便的判断出子树之间的连边? 不管了,反正随便和我重写的 std 做法很像,代码复制黏贴一点改几句话就过了。糖糖的。 考虑类似删边 MST 的做法。删边 MST 要把贡献放到边上,我这里还是放到边上,删点就是删掉相邻边,然后就寄了。 把贡献放到点上,然后就全对了。子树可以连到一个祖先,或者连到其他子树。连到祖先的部分是链上 checkmin 然后单点求值。这个大力树剖,或者一个很简单的写法是对权值从小到大排序,覆盖一个点就删一个点,这里可以并查集维护删点,删点就是合并到父亲。 发现 $(u,v)$ 只可能是删掉 $\operatorname{lca}(u,v)$ 的时候才会用这条边合并两个子树。这样的话一条边只会在一个点贡献。均摊是对的。然后再做一个 $\mathcal O(deg)$ 个点的 MST。 代码非常好写!!1 但是不妨碍我模拟赛的时候和弱智一样!!1 <https://mna.wang/contest/submission/766572> # 20250205 模拟 T1 有 $n$ 个点 $x_i$,每次从 $x_i$ 出发必须跳到 $[x_i+L,x_i+R]$ 之间的一个点 $x_j$。 每个点 $x_i$ 有元素 $a_i$。找到一个跳跃方式,使得经过的 $a_i$ 降序排序之后字典序最大。 无法到达输出 $-1$。 $1\leq n\leq 5\times 10^5$,$1\leq x_i,L,R\leq 10^9$,$1\leq a_i\leq n$,$x_i\lt x_{i+1}$。 ## 特殊性质 $a_i$ 是排列。 zzk 说是因为不知道怎么放部分分放了个这个。他不知道怎么做。 我也不知道哈哈。 好像是说按位贪心可以做。但是想到这个就死翘翘了。和正解一点关系没有,大概是没法优化到正解复杂度的。 ## Sub 1 $n\leq 500$。 发个考场时的笔记。 > 枚举点 $i$,枚举前驱点 $j$。 > > 每个点维护一个序列表示目前的答案方式 > > 点 $i$ 的最优序列是点 $j$ 在某个位置插入 $a_i$ 得到的 > > 比较大小二分 lcp。序列只要维护一个前缀 hash 然后可以单点求值即可。 哈哈这个是正解。三方是实现这个暴力用 vector 然后暴力枚举 $j$ 比较。 代码不想交梦熊,这里贴一下主函数。 ```cpp int main() { read(n, L, R); for (int i = 1; i <= n; i++) read(p[i]); for (int i = 1; i <= n; i++) read(a[i]); vec[1] = {a[1]}; for (int i = 2; i <= n; i++) { int l = lower_bound(p + 1, p + n + 1, p[i] - R) - p; int r = upper_bound(p + 1, p + n + 1, p[i] - L) - p - 1; for (int j = l; j <= r; j++) { if (vec[j].empty()) continue; auto v = vec[j]; auto it = v.begin(); for (; it != v.end(); it++) { if (*it < a[i]) { v.insert(it, a[i]); break; } } if (it == v.end()) v.insert(it, a[i]); checkmax(vec[i], v); } } write(vec[n].size(), '\n'); for (int i : vec[n]) write(i, ' '); putchar('\n'); return 0; } ``` 缺失部分在梦熊交了 $\mathcal O(n^2\log n)$ 的。不影响理解。 但是这个是错的,我没判 -1。 ## Sub 2 $n\leq 5000$。 $n\leq 500$ 的做法转移是一个提取区间 max。套个单调队列或者线段树就好。我写了个线段树,复杂度 $\mathcal O(n^2\log n)$。 <https://mna.wang/contest/submission/767064> ## 正解 首先这个转移形式是一段区间的 max 并且区间端点单调,所以可以单调队列维护。 开一个主席树,支持单点插入即可。 找 lcp 可以用 sum hash。看左子树的 hash 是不是一样,如果左子树一样就找右子树。为了避免冲突提前把每个 $[1,n]$ 映射到 $[0,p)$。 然后似乎没什么难写的,注意一下这题从大到小主席树值域要倒过来。 <https://mna.wang/contest/submission/776878> # 20250205 模拟 T2 省流:Monster 的 DAG 版本。 给定 DAG,每个点有一个怪兽两条属性,花费 $a_i$ 血量击杀他然后回复 $b_i$ 滴血。求最小初始血量。 原题:<https://qoj.ac/contest/1221/problem/6406>。 $2\leq n+m\leq 72$,$1\leq a_i,b_i\leq 10^{15}$。 这个题有点乱,晚点好好补一下各档分的做法。 先写一下我的赛场做法。最高目前过了 96pts 的分。 数据很小,模拟退火,甚至还是阉割版,我不会完整的模拟退火。先随便拉一条 DFS 序下来,然后直接随机交换,更优就替换答案。然后次数开大点用 bitset 存一些目前可达的点集就差不多了。随便来一发就 84 了。随便调调参可以 96。 <https://mna.wang/contest/submission/767450> 然后为了获得 100 分,我们缝合一下 Cfz 的,数据分治一下。 > 显然有一个状压 DP。 > > 但是状态数不满。 > > 直接 map 存状态然后 BFS。 就过了。 Cfz 这个可以加点神秘的东西不是我这个做法给数据分治成 100。 **后续补。** # 20250205 模拟 T3 求 $n$ 个盒子放 $m$ 个左括号,每个盒子都是合法括号序列,并且不存在一个盒子有 $k$ 个左括号的方案数。 $1\leq n,m\leq 10^7$,$1\leq k\leq m$,$10^8\leq p\leq 10^9+7$。 反射容斥和拉格朗日反演啥的都太难了,来点我学得会的做法。 首先显然套一个容斥,把不能有 $k$ 个左括号的限制消掉。然后 DP。$f_{i,j}$ 表示 $i$ 个盒子装 $j$ 个左括号的方案数。 这个有个显然的 $\mathcal O(n^3)$ 的,枚举这个盒子放多少左括号,转移显然。 这样就三方了。 ## 特殊性质 1 $k=m$。 我也不知道是什么,会这个就会整个题了吧。 ## 特殊性质 2 $p=998244353$。 一眼 NTT。但是有人说被卡常了,反正我不会 NTT 不关我事 >_< ## 正解 先随便说个东西。这个 $f_{i,j}$ 打表出来形如 ```plain 1 0 0 0 0 0 0 0 0 0 0 1 1 2 5 14 42 132 429 1430 4862 16796 1 2 5 14 42 132 429 1430 4862 16796 58786 1 3 9 28 90 297 1001 3432 11934 41990 149226 1 4 14 48 165 572 2002 7072 25194 90440 326876 1 5 20 75 275 1001 3640 13260 48450 177650 653752 1 6 27 110 429 1638 6188 23256 87210 326876 1225785 1 7 35 154 637 2548 9996 38760 149226 572033 2187185 1 8 44 208 910 3808 15504 62016 245157 961400 3749460 1 9 54 273 1260 5508 23256 95931 389367 1562275 6216210 1 10 65 350 1700 7752 33915 144210 600875 2466750 10015005 ``` 然后观察一下,第 $1$ 行和第 $2$ 行只差一位,而第 $1$ 行是卡特兰数,说明第 $2$ 行是一个类似卡特兰数的转移,多个 $\pm 1$。然后撞几个式子就出来了。令人汗颜。 <https://mna.wang/contest/submission/768314> 这个正经做法我还不会,晚点写。 **后续补。** # 20250206 模拟 T1 给定长度为 $n$ 的序列 $x_i$。定义 $f(x_i)=(a\oplus x_i)-b$,其中 $\oplus$ 是异或。 有 $q$ 次操作每次形如: 1. `1 k v` 表示 $x_k\gets v
  1. 2 a b 表示求出一个 i 满足 f(x_i)f(x_{i+1})\leq 0。无解输出 -1
## 特殊性质 不带修。 <https://qoj.ac/problem/9669> 和正解一起讲,事实上会了这个就会正解了。 ## 正解 我很不理解这个题出出来有什么意义,如果只是为了科普这个题很牛逼的这个做法完全可以开成强制在线。$10^6$ 卡掉了 $\log^2$ 也卡掉了正解的 $\log$。 不带修的版本求出最小的 $f(x)$ 和最大的 $f(y)$,那么如果有 $f(x)f(y)\leq 0$ 那么一定有解。 我们可以考虑如果此时还有一个 $z$ 那么 $f(x)f(z)$ 和 $f(y)f(z)$ 一定有一个 $\leq 0$。原因显然。 那么我们直接分治就对了。每次取 $mid=\frac{x+y}{2}$,然后递归跑下去。直到区间长度为 $2$。 带修的话在字典树的叶子结点加一个可删堆就好了,小心一些空间什么的。 糖题。线下评测还把我空间卡了。麻麻思乐。 <https://mna.wang/contest/submission/768709> # 20250207 模拟 T1 每次操作选择当前位置抬高一格或者下个位置降低一格。操作永久保留。走到 $n$ 就回到 $1$。高度相同才可以通行。问走 $k$ 轮的最小操作次数。 ## 正解 太简单了不写部分分做法了。 不难发现一个位置如果下降了就不会上升。而且下降的一定是后缀。所以需要先把后缀拍平。 然后 $k=1$ 答案就是极差,因为可以证明我们做降低操作是不优的。这说明我们每一轮答案都是极差。 然后继续观察一下每一轮相当于是删掉了最左侧的元素。那么直接前缀和维护一下就做完了。 <https://mna.wang/contest/submission/770764> # 20250207 模拟 T2 构造不超过 $V$ 个点 $E$ 条边的有向图使得外向基环树大小是 $k$。 $V=80$,$E=220$,$1\leq k\leq 10^{18}$。 **可以有重边和自环。** ## Sub 1 & Sub 2 $V=130$,$E=400$,$1\leq k\leq 10$。 $V=130$,$E=400$,$1\leq k\leq 100$。 直接连 $k$ 条边就做完了。 ## Sub 3 $V=130$,$E=400$,$k=2^t(0\leq t\leq 20)$。 构造 $t+1$ 个点的链,中间每个点连 $2$ 条边。 ## 正解 这是 std 做法。 ![](https://cdn.luogu.com.cn/upload/image_hosting/yv7k11wq.png) 然后是 Cfz 做法。 妈的我赛时做了个完全一样的做法啊???然后我和【数据删除】赛时开黑,我俩认为我的做法应该对着加法构造加法器。但是这个很糖,做不了,因为一条边的贡献和两条边是不一样的。他并不是局部做了一个乘法最后可以加回来。然后发现这个东西啥都过不去。 但是这个做法的式子其实是加法乘法拼起来了,所以可以改。 ![](https://cdn.luogu.com.cn/upload/image_hosting/ow34q9qg.png) 这个方案数是 $AB+AC+CD$。同理画更多点的图出来。 ![](https://cdn.luogu.com.cn/upload/image_hosting/gy4o8luz.png) 我们令 $A=B=E=F=1$,那么方案数是 $1+D(1+G)$。 同理边上连 $k_i$ 条生成树个数就是 $1+k_1(1+k_2(1+\dots))$。 然后这个直接就好了。。。奇数连一条偶数连两条是 $\log$ 但是常数倍。这个问题不大,奇数找一下 $\leq 7$ 的质因子除掉,就过了。 # 20250207 听课笔记 随机算法。 Monte Ciallo 算法