2023.8.4 cmd杂题选讲
数据结构
P4062 [Code+#1] Yazid 的新生舞会
定义出现次数超过区间长度一半的众数为“强众数”
我们可以枚举强众数 \(w\),并枚举它能贡献的区间,设 \(B_i=[A_i=w]\),令 \(S\) 为 \(B\) 的前缀和,则区间 \((l,r]\) 是“新生舞会的”的充要条件是:
记 \(C_i=2S_i-i\),问题就转化为顺序对计数。可以用树状数组优化到 \(O(n^2\log n)\)
注意到,\(B\) 中 \(1\) 的个数是 \(O(n)\) 的,因此在两个 \(1\) 之间的 \(C_i\),是一个公差为 \(-1\) 的等差序列
按照 \(1\) 划分,共有 \(O(n)\) 个等差序列,注意到等差序列的内部是没有贡献的,于是我们逐个插入等差序列,记录前面对它的贡献。
假设当前这段等差序列为 \(y,y-1\dots x\),用数据结构维护它的权值 \(val_i\) 就是区间 \([x,y]\) 里的数 \(+1\)
设 \(T_i=\sum\limits_{j=1}^ival_i\) 表示权值 \(val\) 的前缀和,那么段内的每个位置 \(C_i\) 的贡献就是 \(T_{C_i-1}\),整个段的贡献就是 \(\sum\limits_{i=x-1}^{y-1}T_i\)。再记 \(G_i=\sum\limits_{j=1}^iT_j\) 表示 \(T\) 的前缀和,那区间的贡献就是 \(G_{y-1}-G_{x-2}\)
于是问题转化成区间加一个数和求二阶前缀和,将区间加一个数转化成差分数组 \(d\) 的单点修改,就可以用树状数组维护三阶前缀和
现在思考如何维护三阶前缀和。设 \(a\) 是 \(b\) 的前缀和,\(b\) 是 \(c\) 的前缀和,\(c\) 是 \(d\) 的前缀和
用树状数组维护 \(d_t,d_t\times t,d_t\times t^2\) 即可
P7476 「C.E.L.U-02」苦涩
标记永久化的好题
每个节点维护一个堆和一个最大值标记 \(dat\)
操作 \(1\) 和 \(3\) 暴力做即可,重点讨论操作 \(2\)
对于完全覆盖的区间,如果节点堆顶等于 \(x\) 就弹出,否则继续往下递归删除
否则的话,首先要下传标记。如果该节点堆顶等于 \(x\),就将 \(x\) 弹出并下传到两个儿子中。之后递归删除即可
复杂度不太会算,但是说是 \(O((n+m) \log^2 n)\)
P5344 【XR-1】逛森林
倍增优化建图,每个点向上的 \(2^{0\sim t}\) 级祖先连边,分为内向和外向
这样点数是 \(O(n\log n)\) 的,边数是 \(((n+m)\log n)\) 的,加上 \(\rm Dijkstra\) 的时间复杂度就是 \(O(n(n+m)\log^2 n)\) 的
考虑到题目只要求跑最短路,所以可以像 \(\rm ST\) 表一样,重复建边,边数就是 \(O(n\log n)\) 的,总的时间复杂度 \(O(n\log^2 n)\)。
CF348C Subset Sums
遇到这种比较难维护的数据结构,又有 \(\sum |S|\leq 10^5\),容易想到根号分治。
对于 \(|S|\leq \sqrt{n}\) 的,暴力修改,暴力查询。预处理每个大集合和其它集合的交集,小集合修改时计算对大集合的贡献。
对于大集合,修改直接打标记,并计算对其它大集合的贡献。查询输出标记总和+原和即可。时间复杂度 \(\mathcal{O}(n\sqrt{n})\)。
ビ太郎のパーティー (Bitaro's Party)
还是根号分治。
对于 $Y_i>\sqrt{n} $ 的,暴力 DP。
对于 \(Y_i\leq \sqrt{n}\) 的,我们只关心最短的 \(\sqrt{n}\) 条路径,这个可以 DP 时归并得到。
复杂度 \(\mathcal{O}(n\sqrt{n})\)。
图论
[AGC011C] Squared Graph
考虑 \((x,y)\) 和 \((x',y')\) 在一个连通块的条件。将新图中 \((a,b)\rightarrow (c,d)\) 的边看作是从 \(a\) 走到 \(c\),从 \(b\) 走到 \(d\)。因为可以来回走,所以 \((x,y)\) 和 \((x',y')\) 在一个连通块的充要条件就是原图存在一条 \(x\rightarrow x'\) 和一条 \(y\rightarrow y'\) 的路径,且路径长度相差偶数。
对于原图,发现若一个连通块存在奇环,则任意两点间有一条长度为奇数和一条长度为偶数的路径。否则可以二分图染色,颜色相同的点之间路径长度为偶数,否则为奇数。
将原图所有连通块分为三类:奇环、二分图、孤立点。分别记数量为 \(A,B,C\)。现在将不同种类的连通块放到其中一维上,去匹配另一维。
-
对于一个奇环来说,自己与自己匹配产生 \(1\) 的贡献。与其它奇环匹配可以产生 \(2\) 的贡献。
-
对于一个二分图,自己与自己匹配产生 \(2\) 的贡献(颜色相同/不同),与其它二分图匹配产生 \(4\) 的贡献,与奇环匹配产生 \(2\) 的贡献。
-
对于孤立点,自己与自己匹配产生 \(1\) 的贡献,与其它所有点匹配产生 \(2\) 的贡献。
时间复杂度 \(\mathcal{O}(n)\)。
CF741C Arpa's overnight party and Mehrdad's silent entering
容易想到二分图染色,在情侣之间连边。问题是三个人的限制如何处理。
我们发扬人类智慧,钦定 \(2i\) 和 \(2i+1\) 号节点颜色不同。可以证明这一定是个二分图。
然后跑染色即可。
CF1407E Egor in the Republic of Dagestan
容易想到从 \(n\) 点出发贪心染色。直接 bfs 即可。
CF1515F Phoenix and Earthquake
将原题看成是建生成树的过程。当 \(\sum a<(n-1)x\) 时无解,否则,猜想任意一棵生成树都有解。
证明:使用归纳法。我们任取一棵生成树 \(T\)。找到一个叶子节点 \(u\):
-
若 \(a_u\ge x\):则此时直接建 \((u,fa)\) 这条边,剩下的 \(n-1\) 棵节点的树有解。
-
若 \(a_u<x\):则对于除了 \((x,fa)\) 这条边的树 \(T'\),因为 \(\sum a\) 减少了 \(a_u\),\((n-1)x\rightarrow (n-2)x\),所以必定合法。那我们将 \((x,fa)\) 放到最后修建即可。
于是,我们用一个栈和队列维护答案即可。
P3573 [POI2014] RAJ-Rally
问题的关键在于原图是一个 DAG,这启发我们按拓扑序考虑每个节点。将拓扑序小于 \(i\) 的节点集合记为 \(A\),大于 \(i\) 的集合记为 \(B\)。预处理 \(ds_x,dt_x\) 分别表示从以 \(x\) 为起点/终点的最长路,则此时的答案就是 \(\max\{dt_x(x\in A),ds_y(y\in A),ds_x+1+dt_y(x\in A,y\in B)\}\)。
一开始将所有所有点都放在集合 \(B\),用 multiset 维护上述值。删除一个点时删除对应的值,然后再加到集合 \(A\) 即可。时间复杂度 \(\mathcal{O}(m\log m)\)。
CF986C AND Graph
CF605E Intergalaxy Trips
设 \(E_i\) 表示 \(i\rightarrow n\) 的期望天数。如果 \(i\) 选择 \(j\),则此时所有 \(E_k<E_j\) 的 \(k\) 都无法作为决策点。并且决策点必然满足 \(E_j<E_i\)。
假设已经完成转移的点为 \(q_1,q_2,\dots ,q_m\) 且满足 \(E_{q_i}<E_{q_{i+1}}\)。则
但此时我们计算的 \(E_i\) 仅仅是与 \(i\) 相连的通道中至少一条开启时的贡献,可能存在通道一条都没开启的情况。至少一条开启的概率是 \(1-\prod (1-p_{i,j})\)。所以期望天数应该是 \(\dfrac{E_i}{1-\prod\limits_{j}^{E_j<E_x}(1-p_{i,j})}\)。
上述转移方程就变成
使用 dijkstra 即可。
CF1559D2 Mocha and Diana
猜想答案等于 \(\min(n-1-m_1,n-1-m_2)\)。
我们随便拿出一个点,假设是 \(1\)。我们先让能和 \(1\) 连的点全连上。记没和 \(1\) 连的连通块分别为 \(A,B\),则必有 \(A\cap B=\varnothing\)。所以只需 \(A,B\) 内暴力连边即可。
其它
P6811 「MCOI-02」Build Battle 建筑大师
对原序列
[AGC006C] Rabbit Exercise
对于每次跳跃,\(x_i\) 的期望位置为 \(x_{i-1}+x_{i+1}-x_i\),可以直接维护。但问题是 \(k\) 太大了。
这个式子很复杂,于是我们可以考虑差分,设 \(d_i=x_i-x_{i-1}\)。那么每次操作后
所以每次操作相当于交换相邻的差分数组。记录交换的映射,类似快速幂可以做到 \(\mathcal{O}(m\log k)\)。
CF1153F Serval and Bonus Problem
先将线段长度除以 \(l\),变成长度为 \(1\),最后再乘回去。
那么其实就是求出每个点的被 \(k\) 个区间覆盖的概率,再积分回去,而线段长度为 \(1\),所以就是求概率。
然后我们惊奇地发现这可以 DP,设 \(f_{i,j,0/1}\) 表示已经选了 \(i\) 个左端点,还有 \(j\) 个没匹配上,采样点是/否被选上时被 \(k\) 个区间覆盖的方案数。转移即考虑加入一个左端点、右端点、采样点。
最后我们要求的就是 \(f_{2n+1,0,1}\),那么概率就是 \(\dfrac{f_{2n+1,0,1}\times 2^n\times n!}{(2n+1)!}\)。(线段的两个端点可以互换,线段的顺序也可以互换。)
[ARC072F] Dam
没什么好说的,请看 题解【[ARC072D] Dam】。

浙公网安备 33010602011771号