Solution Set #8

状态开始回暖了,但是还是好菜/kk

134 qoj3998. The Profiteer(背包,分治)

套用决策单调性的分治,查询最优端点的时候二分查找,可以做到 \(\mathcal{O}(nk\log^2 n)\)

上面的做法是可以优化的:二分的时候把确定的范围直接加入,这样就是 \(\mathcal{O}(nk\log n)\) 的了。

https://qoj.ac/submission/304529

135 qoj1173. Knowledge Is...(贪心)

大力贪心,把所有区间按照 \(l\) 排序,如果能够匹配没有匹配的区间,那么直接匹配。否则,拆一个右端点最小的匹配,然后把当前区间和这个区间匹配。

可以使用线段树维护。但实际上如果一个匹配的左侧区间和右侧区间都能匹配,那么拆左边或者拆右边效果是相同的。

https://qoj.ac/submission/305547

136 qoj5357. 芒果冰加了空气(DP,计数)

考虑对于每个子树构造点分治方案,然后合并。

先考虑 \(u\) 为分治中心的时候连通块大小为 \(1\) 的情况。那么假设子树 \(v\) 中有 \(c_v\) 个连通块与 \(u\) 接触,那么方案数是 \(\binom{\sum c_v}{c_{v_1},c_{v_2},\cdots c_{v_k}}\)。否则,当 \(u\) 的联通块大小不为 \(1\) 的时候,我们可以考虑 \(v\) 的子树中有 \(d_v\leq c_v\) 个联通块层数比 \(u\) 浅,那么方案数就是把 \(c\) 换成 \(d\)

直接在树上 DP,复杂度为 \(\mathcal{O}(n^2)\)

https://qoj.ac/submission/306315

137 qoj6101. Ring Road(分治,最短路)

边分治,每次处理跨过两个联通块的最短路。

由于连接两个联通块的边只有 \(\mathcal{O}(1)\) 条,所以把这些边单独提出来跑最短路即可。

Submission #307392 - QOJ.ac

138 qoj970. Best Subsequence(贪心,整体二分)

发现如果相邻的两个数都 \(\leq \frac{W}{2}\),那么它们之间相当于没有限制。可以构造出一组解使得这些数全部被选上。把 \(>\frac{W}{2}\) 的元素选上,只需要在每个连续段选一个最小的即可,施调整法可以证明这样是最优的。

考虑整体二分 \(W\),从小到大扫描 \(W\),使用 set 维护 \(\leq \frac{W}{2}\) 的集合以及每个连续段的最小值,用树状数组做区间询问可以求出其中有多少个 \(\leq \frac{W}{2}\) 的元素和 \(>\frac{W}{2}\) 的元素。可以在外层循环 \(30\) 次来达到二分的效果。

Submission #307418 - QOJ.ac

139 qoj6638. Treelection

相当于限制除了 \(u\) 之外,其它每个结点不能放超过 \(sz_u-2\) 个票。

先不考虑 \(u\) 的特殊性,考虑贪心,每次把票放在最深的祖先上。维护 \(f_u\) 表示 \(u\) 子树内还有多少票,转移是 \(f_u=\max(\sum f_v-X,0)+1\),合法条件是 \(f_1=1\)

假设 \(u\) 的子树也满足 \(sz_u-2\) 的限制,那么 \(u\) 的特殊性被消除,答案只和 \(sz_u-2\) 与最小合法 \(X\) 的大小关系有关,可以二分求出 \(X\)。否则,我们需要额外考虑 \(X=sz_u-1,f_1=2\) 的情况。此时我们需要判断 \(f_1\) 中多出的票能不能删去,合法条件即为对于 \(u\) 的所有祖先 \(anc\) 都有 \(f_{anc}>1\)

Submission #306471 - QOJ.ac

140 qoj6540. Beautiful Sequence(贪心)

钦定集合 \(S,T\) 使得 \(S\) 为满足条件的元素而 \(T\) 不是。

考虑判断合法,将 \(S\) 中元素去重并从大到小排序,\(T\) 中元素从大到小排序,那么合法条件是 \(T_i\leq \min(S_i,S_{i+1})\)(如果不存在元素,则视作 \(-\infty\)

考虑先钦定 \(S\) 是全集,从 \(S\) 中删去元素使得合法,最终的目标是最小化 \(T\) 中元素个数。注意到最终的 \(T\) 满足 \(|T|=|S|-1\)\(|T|\) 是可重集),而对于一次删除操作,如果我们删去的元素是最后一个,那么 \(|T|\gets|T|+cnt_u\)\(|S|\gets |S|-1\),否则,\(|T|\gets|T|+cnt_u\)。注意到前者是更优的,所以我们会贪心选 \(cnt_u\) 尽量小的元素。所以可以把所有数按照 \(cnt_u\) 排序,从小到大能选则选。可以证明这样是正确的(考虑唯一的问题是我们选了一个出现次数较少但值较大的元素,可能影响后面的判断,但其实可以大力调整)。

暴力实现可以平方,考虑优化判断的过程。注意到我们把 \(T\) 中的元素看作数轴上的一个 \(-1\)\(S\) 中的元素看做 \(1\),条件相当于折线始终不会碰到 \(y=0\)。线段树维护即可。

Submission #307238 - QOJ.ac

141 2024.1.16 cheer(差分,gcd)

题目大意

注意到差分之后 \(\gcd\) 不变,考虑差分。差分后一次操作只会改变 \(4\) 个点的权值。

任意选 \(5\) 个点,答案一定是这 \(5\) 个点点权的 \(\gcd\) 的因数。对于它的每个素数因子 \(p^k\) 考虑。分类讨论:

  • 没有点不被 \(p^k\) 整除,直接加。
  • 恰好 \(2\) 个点被 \(p^k\) 整除,那么只有修改祖先链才有用。
  • 恰好 \(4\) 个点被 \(p^k\) 整除,那么只有确定的路径有用。

所以我们只需要考虑 \(\log V\) 条路径的答案,暴力即可。

142 2024.1.17 tree(MST,边分治)

题目大意

大力 boruvka 可以得到 \(\mathcal{O}(n\log^3 n)\) 做法。

考虑大力优化这个做法。注意到瓶颈在于边分治中的排序,而每次 boruvka 排序的过程是相同的。所以可以直接把分治过程离线,求最短边的部分双指针解决。复杂度 \(\mathcal{O}(n\log^2 n)\)

143 CF1158E Strange device(树交互,并行操作)

操作明示把树分层。

考虑二分,每次询问出距离 \(l\) 不超过 \(mid-l-1\)\(mid-l\) 的结点,那么可以把点分成 \([l,mid),[mid,mid],(mid,r]\) 三类。

考虑并行,每次找到所有二分的区间,一次把所有奇数或所有偶数的区间割开,可以做到 \(4\log n\) 的操作次数。

然后询问每一层,可以按照模 \(3\) 的余数分层,然后二进制分组一下,然后并行一下,就可以做到 \(3\log n\) 了。

https://codeforces.com/contest/1158/submission/242177866

144 qoj962 Thanks to MikeMirzayanov(排序,构造)

先转化一下操作:区间翻转,然后再全局翻转。

一个套路:先考虑给 \(01\) 排序,然后通过分治将问题转化成给 \(01\) 排序。

考虑怎么给 \(01\) 排。先把一个连续段缩起来,然后问题是给 \(01010101\cdots\) 排序,我们把第奇数个 \(01\) 对翻转,偶数不变,每次可以让连续段数量减半。所以可以在 \(\log n\) 时间排序 \(01\)

回到原题,我们分治下去,然后并行操作,可以做到 \(\log^2 n\) 次操作,常数较小,但是还是要卡一下。

https://qoj.ac/submission/307627

145 JOI Open 2019 Triple Jump(线段树,支配对)

在单调栈上观察,可以发现只有在单调栈过程中相邻的两个 \((a,b)\) 有用,所以原问题 \((a,b)\) 的支配对数量是 \(\mathcal{O}(n)\)

但是带上 \(c\) 则还需要一个后缀 \(\max\) 操作。挂到线段树上观察,相当于维护二元组 \((A_i,B_i)\)

  • \(B_i\gets \max(B_i,A_i+x)\)
  • \(A_i\gets \max(A_i,x)\)
  • 区间询问 \(B_i\) 最值。

直接使用线段树是可以维护的。

https://loj.ac/s/1986350

146 NOI 2020 超现实树

好像没那么难?

先考虑链的包。要求对于左右儿子均可以生成,分类讨论:

  • 如果存在一棵树是单点,答案是 Almost Complete。
  • 否则,把只有左儿子的链往左递归判断,只有右儿子往右递归判断。

一般的情况只需要额外考虑有两个儿子的情况。考虑一个构造非法解的方式:左儿子挂一个单点,右儿子递归构造。此时集合 \(\mathcal{T}\) 中能够用来生成右儿子的树的个数是最少的,即满足左儿子是单点的树。把这些树拿出来递归处理即可。

https://loj.ac/s/1982846

147 QOJ 1436 Split in Sets(贪心)

先考虑 \(a_i=2^k\) 的做法,那么如果最高位有 \(\geq k\) 个那么一定是铺满,然后剩下的数全部放一个里面。

可以得到一个结论:如果最高位有 \(\geq k\) 个,那么一定只有一个桶的 and 值不是最高位。因为如果多个最高位堆一起,可以把两个较低位合并然后把最高位单独拉出来。较低位的影响是 \(a+b-a \text{ and } b=a \text{ or } b\),不会比增大的值还大。

注意到如果所有数最高位都相同,那么可以把最高位删去,然后直接把最高位的贡献计算。

根据上述性质,设计 \(\text{solve}(a,k)\) 表示求解的算法。

  • 所有数最高位相同,计算最高位贡献,递归。
  • 计算最高位数的数量 \(cnt\),若 \(cnt<k\),那么选 \(k\) 个位置把最高位单独放,其余数递归下去。
  • 否则,其它数一定放在同一个桶里面,把它们与起来变成一个数,计算最高位贡献,递归。

计数是简单的。

https://qoj.ac/submission/309735

148 2024.1.22 模拟赛 emotion

问题约等于对 \(n\) 的所有子集 \(S\) 求生成树个数 \(f(S)\)

有转移式子:

\[f(S)=\frac{1}{2|S|-2}\sum_{T\subsetneq S}f(T)f(S-T)E(S,T) \]

可以使用子集卷积优化到 \(\mathcal{O}(2^nn^2)\)

149 qoj2065. Cyclic Distance(凸优化)

考虑确定点集之后怎么做,可以拿重心构造出两倍虚树大小。

考虑 DP,加一条边的贡献是 \(\min(i,k-i)w\),合并子树是 \((\max,+)\) 卷积,所以是凸的,跟 THUPC 那题一样拿对顶堆维护一下就好了。

https://loj.ac/s/1986350

posted @ 2024-01-20 22:01  yllcm  阅读(243)  评论(2编辑  收藏  举报