在 Cometoj 随机看了一套题。是 Sooke 大仙他们的。
代码打算明天写,我希望可以在 4h 内写完吧...>_<
u1s1 D2T3 的卡空间感觉非常的仙啊...
Day1
A
给定 \(T\) 组查询,每次给定序列 \(a\) 和 \(b\)
定义一次操作为:选择 \(a\) 的一段区间和区间中的一个下标 \(i\),然后记 \(S\) 为区间权值和,然后清空区间,然后令 \(a_i=S\)
求最少操作多少次使 \(a=b\)
Solution
感觉是直接从前往后做,假设 \(a_i\ne b_i\),那么就往后找,沿途的 \(b_i\) 都必须是 \(0\),然后给 \(a_i\) 赋值即可。
当然,如果 \(b_i=0\) 那么就直接往后跑就可以了。
然后特判非法。
B
给定一张图,第 \(i\) 条边的权值是 \(2^i\),多组查询,每次给定 \(s_i,t_i\),求 \(s_i\to t_i\) 的最短路。
保证图联通。
\(n,m,q\le 3\times 10^5\)
Solution
求最小生成树。(不难注意到 \(2^i\) 的影响是绝对的)
然后变成查路径权值和了,差分 + LCA 即可。
C
给定长度为 \(n\) 的序列 \(a_{1,2...n}\),支持 \(q\) 次修改,每次将 \(a_i\) 改为 \(x\)
每次修改后输出,从大到小排序后的 \(\frac{1}{4}\times (\frac{3}{4})^i\times a_i\) 的权值和。答案取模。
Solution
这 tm 不是 sb 题吗
一个值域线段树,没了。
Day2
A
给定 \(n\) 个矩形,范围为 \(r\cdot c\),求多少个位置满足至少有 \(n-1\) 个矩形覆盖了其。
\(n\le 2\cdot 10^5,r,c\le 10^9\)
Solution
出得好!
将位置分类,分为:
- 被所有矩形覆盖,这里只需要求一下矩形交即可。
- 被除某个矩形外的其他所有矩形覆盖,显然被去除的矩形唯一。
前者可以直接计算,后者不妨考虑枚举被去除的矩形是谁,那么只需要其他矩形的交 \(\to\) 知道前缀后缀的交,然后只需要统计在矩形 A 外但是在交内的点数,可以直接计算面积减去整体的交。
复杂度 \(\mathcal O(n)\)
B
给定一个 \(n\) 个点的链,有若干条边连接了这些点,每条边只能在链的上方或者下方,边之间不能相交,每个点的度数 \(d_i\) 给定,如果在点 \(i\) 与点 \(i+1\) 之间画一条竖线,那么要有恰好 \(p_i\) 条边穿过其,求合法的连图方案数。
请注意,一条边连接在上部与下部也被视为不同的连边方案。
答案对 \(998244353\) 取模。
\(T\le 10,n\le 2000,0\le d_i,p_i\le n\)
Solution
问题等价于,将长度为 \(n\) 的序列拆分成上下两个括号序列的方案数(大概)
于是会发现对于点 \(i\) 而言操作完之后剩余的 L 端点数的和要恰好为 \(p_i\)
所以合法的状态只有 \(f_{i,0,p_i}...f_{i,p_i,0}\) 这种东西。
于是复杂度是 \(\mathcal O(\sum p_i)\) 的,即 \(\mathcal O(T\cdot n^2)\)
转移要用前缀和优化一下即可。
C
给定一棵树,每个点有一个权值 \(w_i\),其中一条边为黑色当且仅当其连接的两个点的点权 \(\&\) 值为 \(0\),否则其为白色,求白色边连接构成的联通块数。支持修改单点点权。
设 \(n\) 为树的大小,\(q\) 为查询次数,则:
- \(n\le 10^5,q\le 10^5,\max\{w\}< 2^{20}\)
Solution
方便起见设 \(m=16\),即值域变小一点...
首先树上的联通块数为 \(n-边数\),注意到边数可以视为总边数减去黑色边数,那么只需要统计黑色边数即可。
我们先考虑一个单次修改 \(\mathcal O(2^m)\) 的暴力做法,对于树上节点进行修改,我们将每个点的贡献定义在其父亲上,对于每个父亲维护 \(f_{x,o}\) 表示其儿子中权值为 \(o\) 的点的数量,那么每次修改只需要修改当前节点的父亲的 \(f\) 数组,修改后我们需要统计当前的黑色边数,那么特判一下当前节点与父亲,同时 \(\mathcal O(2^m)\) 的枚举自己的儿子节点来查询即可。
接着让我们来考虑另一种 \(\mathcal O(2^m)\) 的做法,设当前将 \(x\) 点权改为 \(col\),注意到上述做法在实现的过程可以视为查询 \(f_{x,o}\) 数组中满足 \(o\& col=0\) 的 \(f_{x,o}\) 的权值和,然后单点修改父亲的 \(f\) 数组,这样的话,我们考虑做到 \(\mathcal O(2^m)\) 的修改和 \(\mathcal O(1)\) 查询,即不妨考虑设 \(g_{x,o}\) 表示查询节点 \(x\) 权值为 \(o\) 时的答案,那么修改时考虑暴力枚举父亲的 \(f\) 数组的所有 \(o'\),统计满足 \(o'\&col=0\) 的 \(o'\) 并将贡献加入其中。
注意到实现的过程可以拆分为修改+查询,总有一边为 \(\mathcal O(2^m)\) 另一边为 \(\mathcal O(1)\),考虑平衡复杂度,两边同时做到 \(\mathcal O(2^{m/2})\),不妨考虑,每次修改对于父亲节点的 \(f_{u,o}\) 数组进行折半,对于前 \(m/2\) 位,我们暴力枚举所有位置 \(t'\) 满足 \(t'\& col=0\),同时将贡献加入到后半位与 \(col\) 相同的 \(o\) 中,这样查询只需要枚举后半位并统计答案即可。
现在我们得到了一个空间 \(\mathcal O(n\cdot 2^m)\),复杂度 \(\mathcal O(n\cdot 2^{m/2})\) 的做法,然而这还不够,我们考虑进一步优化空间,考虑一个点的 \(\rm deg\),如果 \(\rm deg\le 2^{m/2}\) 那么设这个位置为普通位,否则设为关键位,我们对于普通位进行暴力,对于关键位进行上述算法,这样的空间开销上界为 \(\frac{n}{2^{m/2}}\cdot 2^{m}=n\cdot 2^{m/2}\),时间复杂度为 \(\mathcal O(n2^{m/2})\)。
sto Sooke orz