CSP模拟52 & A 层联测 9

发布时间 2023-10-11 20:47:14作者: -白简-

2023NOIP A 层联测 9

长春花

观察大样例可以发现,函数 \(f(x)\) 的值很小,那么可以考虑暴力枚举。

用一个桶存一下平方数对 \(p\) 取模的值是否存在,那么可以选择从小到大枚举 \(a\),找到第一个存在的 \(b\)

紫罗兰

考虑什么情况下会出现环,当两个点已经连通时,再在这两个点之间加一条边,那么会产生环(不一定是简单环)。

考虑用并查集维护两点是否连通,依次加边。

如果两个结点已经连通,那么可以 BFS 找这两个结点间最短路径,新产生的环的长度即为两点间最短路径长度加 \(1\),这一过程是 \(O(n)\) 的;

如果两结点尚未连通,则无需 BFS,直接建边并查集维护连通性即可。

最多 BFS 次数不会超过 \(m\) 次,那么复杂度不会超过 \(O(nm)\),优于题解的 \(O(n(n +m))\)

天竺葵

本质上是一个带权的最长上升子序列。

先考虑 \(O(n^2)\) 做法,设 \(dp_{i,j}\) 表示前 \(i\) 个数选出长度为 \(j\) 的子序列时,末尾数的最小值。

那么满足 \(a_i > dp_{i-1,j-1} \times b_{j-1}\) 时,有转移 \(dp_{i,j}=\min \left\{ dp_{i-1,j},a_i \right\}\)

考虑怎么优化,可以发现 \(i\) 相同时,\(dp_{i,j}\) 的值随 \(j\) 单调递增,即对于 \(j < k\),有 \(dp_{i,j} < dp_{i,k}\)

那么考虑,对于 \(dp_{i-1,j-1} > a_i\) 时,无法转移,显然找不到这样一个 \(b_{j-1}\) 使得序列合法。

对于 \(dp_{i-1,j-1} \leq a_i\),才有可能转移,那么我们找到第一个大于 \(a_i\) 的位置进行判断并转移。

风信子

考虑复习超级钢琴。

设一个三元组 \((id,l,r)\)\(id\) 表示左端点,\(l,r\) 表示右端点的候选区间。

我们要找到前 \(k\) 个最优的答案,假设我们找到了第一个解的右端点 \(x\),那么 \(\left[ l,x \right)\)\(\left(x,r \right]\) 仍然是一个候选的答案区间,我们把它们放进堆里再去选择下一个答案。

那么对于这道题也用到了这样的思想,左右端点各属于一个区间,那么这个解的集合成为了一个矩形。

假设我们已经有了其中一个解 \((x,y)\),那么考虑去掉这个解之后的候补答案集合是什么。

有两种情况是容易获得候补答案集合的,即左右端点区间重合或相离。

另外的情况就是左右端点集合有相交的部分,可以考虑将其转化为容易处理的类型。

设左右端点区间分别为 \(\left[ l_1,r_1 \right]\)\(\left[ l_2,r_2 \right]\),有 \(l_1 \leq l_2 \leq r_1 \leq r_2\)

那么我们可以把左端点的分为 \(\left[ l_1,l_2 \right]\)\(\left[ l_2,r_1 \right]\);将右端点分为 \(\left[ l_2,r_1 \right]\)\(\left[ r_1,r_2 \right]\)。然后可以让左端点两个区间与右端点区间分别组合,容易发现每一个组合都是相离的。

最后考虑两种容易处理的情况,设最优解位于 \((x,y)\)

左右端点所在区间重合:

左端点 \(\in \left[ l,x-1 \right]\),右端点 \(\in \left[ l,x-1 \right]\)\(x > l\));

左端点 \(\in \left[ l,x-1 \right]\),右端点 \(\in \left[ x,r \right]\)\(x > l\));

左端点 \(\in \left[ x,x \right]\),右端点 \(\in \left[ x,x \right]\)\(x \neq y\));

左端点 \(\in \left[ x,x \right]\),右端点 \(\in \left[ x+1,y-1 \right]\)\(x < y - 1\));

左端点 \(\in \left[ x,x \right]\),右端点 \(\in \left[ y+1,r \right]\)\(y<r\));

左端点 \(\in \left[ x+1,r \right]\),右端点 \(\in \left[ x+1,r \right]\)\(x < r\))。

左右端点所在区间相离:

左端点 \(\in \left[ l_1,x-1 \right]\),右端点 \(\in \left[ l_1,r_1\right]\)\(x > l_1\));

左端点 \(\in \left[ x,x \right]\),右端点 \(\in \left[ l_2,y-1 \right]\)\(y > l_2\));

左端点 \(\in \left[ x,x \right]\),右端点 \(\in \left[ y+1,r_2 \right]\)\(y<r_2\));

左端点 \(\in \left[ x+1,r_1 \right]\),右端点 \(\in \left[ l_2,r_2 \right]\)\(x < r_1\))。

时间复杂度 \(O((n+(\sum k))\log n+(\sum k)\log (\sum k))\)