杂题散做

P2336 [SCOI2012] 喵星球上的点名

同类题:CF710F、SP8093。算是这类匹配问题的集大成者?

本题正解似乎是广义 sam 或者 sa 之类的玩意,但可以不用。考虑一个经典结论:模式串的长度种类是 \(\sqrt{\sum len}\) 级别的。于是你可以对每种长度开一个哈希表,暴力枚举长度 hash 找模式串就是 \(\mathcal{O}(\sum len\sqrt{\sum len})\) 的了。

P3225 [HNOI2012] 矿场搭建

评价是不要看到删一个点之后联通就去想缩点双建圆方树跑 dp,也有可能是割点。

P6370 [COCI2006-2007#6] KAMEN

不会做绿题。

发现暴力遍历的时候很浪费,因为从同一列上丢下来的两个球有很长一段前缀是相同的。考虑记录每一列上丢个球下来的路径,然后每次暴力调整。为什么这样做是对的?发现一个点最多成为一次路径中的点,因为它被弹出的时候说明它被填了,所以复杂度是 \(\mathcal{O}(rc^2)\) 的。

P7831 [CCO2021] Travelling Merchant

不会做蓝题。

\(f_u\) 表示从 \(u\) 开始能无限走的最小初始资产,那么有转移 \(f_v=\min(\max(r_i,f_u-p))\)。发现图上有环不能直接转,考虑一个神奇的转移方式:

把所有边按 \(r\) 从大到小排序,初始时 \(f_i=\infty\),建反图。先跑 topsort,正常转移,然后枚举剩下的边中最大的一条 \((u,v,r,p)\)。此时通过这条边走一定能走到一个环,且路径上所有点的限制都不超过 \(r\),所以这个点的限制就是 \(r\)\(f_v\gets \min(f_v,p)\),然后这条边的转移就没用了,把这条边删掉即可,重复这个流程直到图为空即可求出答案。

P5994 [PA2014] Kuglarz

感觉还好,感觉这个题做法比较经典。令 \(s_i\) 表示前 \(i\) 个杯子下球数的奇偶性,发现询问 \([l,r]\) 会得到 \(s_r\oplus s_{l-1}\),且 \(s_0=0\),那么想知道每个杯子下面有没有球就要知道 \(s_{1\sim n}\) 的值,这就是一个最小生成树。

P5070 [Ynoi2015] 即便看不到未来

鉴定为典,但是脑子没转过来。以及不是很懂为什么 \(n=10^6\) 正解是 \(10\times n\log n\) 的。

以下为初始想法:离线,询问挂到右端点,每个值 \(i\) 维护一个 \(lst_i\) 表示最后一次出现位置。考虑在一个连续段的左端点处统计它。假设这个连续段的左端点为 \(l\),当前询问区间是 \([L,R]\),那么这个连续段的长度不小于 \(len\) 的条件就是 \(lst_{i-1}<L\),且 \(\forall j\in[i,i+len),lst_j\ge L\),那么这个连续段会对 \((lst_{i-1},\max(lst_j)]\) 范围内的 \(L\) 产生贡献。可以枚举 \(len\),每次修改 \(lst_i\) 时暴力修改,复杂度 \(\mathcal{O}(k^2n\log n)\),其中 \(k=10\),显然过不去。

实际上可以更简单的得到复杂度更优的做法。考虑从右端点加入一个数 \(i\) 时会产生的影响。可以把 \(i\) 左右十个数拎出来按 \(lst\) 排序,然后枚举左端点在哪两个点之间,暴力加入/删除贡献。复杂度 \(\mathcal{O}(kn\log n)\)

[ABC319G] Counting Shortest Paths

为什么这么简单的题不会做啊(

考虑先求每个点到 1 的最短路长度。考虑从 1 开始 bfs,维护一个当前还不知道距离的点集 \(s\),每次拓展的时候暴力把删去的边对应的点在点集里删掉,其他的点答案就是当前点加一。显然这样复杂度是 \(m\log n\) 的。

然后考虑求方案数。同样是正难则反,记 \(f_i\) 表示 \(i\) 的答案,那么我们从小到大枚举每一层,当前层中每个点的答案就是上一层的 \(f\) 值之和减去上一层不能到自己的那些点的 \(f\)。复杂度也是 \(m\log n\)

类似?CF1242B,CF920E

CF1242B. 0-1 MST

考虑一个带 log 的做法。考虑从小到大枚举每个点,尝试把它合并到之前的连通块里,如果这个点和一个连通块的断边条数小于连通块个数就需要合并。容易发现只会合并 \(n\) 次,所以带一个 log。

考虑一个线性的做法。找到断边最少的那个点,注意到它最多只有 \(\dfrac{2m}{n}\) 条断边,所以从这个点开始合并完后只会剩至多 \(\dfrac{2m}{n}\) 个连通块,对这些连通块直接暴力合并即可。复杂度 \(\mathcal{O}(n\times\dfrac{2m}{n})=\mathcal{O}(m)\)

[AGC044C] Strange Dance

很经典的一道题。看到全局加一直接想到从低到高建 trie,然后发现这两个操作都可以简单的维护,交换儿子可以打标记,直接做就行了。

同类题:P6018 [Ynoi2010] Fusion tree。似乎这个题是这个经典 trick 的来源。

CF888G. Xor-MST

比较典?考虑模拟 Kruskal 的过程。我们从高到低枚举边权的每一位,记当前状态为 \((a_l\ldots a_r,k)\) 表示需要联通 \(a_l\ldots a_r\),考虑到了第 \(k\) 位。那么可以把 \(a_i\) 按第 \(k\) 位分成两组,递归下去处理。现在只需要联通这两个连通块,开个 trie 即可。复杂度 \(\mathcal{O}(n\log^2 V)\)

好像还有个模拟 Boruvka 的做法,在 trie 上 dfs,本质应该差不多。

P6859 蝴蝶与花

似乎是个很经典的 trick,但我不会()

先判一下 \(k>\sum\limits_{i=1}^n a_i\) 的情况。考虑二分出最小的位置 \(p\) 满足 \(\sum\limits_{i=1}^p a_i\ge k\),显然 \(\sum\limits_{i=1}^p a_i\) 只有可能是 \(k\)\(k+1\)。如果是 \(k\) 就找到了,否则我们找到从 \(1\) 和从 \(p\) 开始的第一个 \(a_i=1\) 的位置 \(p_1,p_2\),考虑不断同时让左右端点加一,那么我们如果想让和减一要么让左端点移到 \(p_1+1\),要么让右端点移到 \(p_2\)。线段树二分即可。

P2150 [NOI2015] 寿司晚宴

妙妙题!考虑暴力。定义 \(f_{i,j,k}\) 表示考虑前 \(i\) 个数,小 G 选的数包含的质因子集合为 \(j\),小 W 选的为 \(k\) 的方案数。当 \(n\le 30\) 时质数只有 10 个,时间复杂度 \(\mathcal{O}(n2^{20})\),可以获得 30 分。

思考当 \(n\le 500\) 时怎么优化。注意到因为每个数只会有至多一个 \(>\sqrt{n}\) 的质因子,记这个因子为 \(b_i\)(没有则为 0)。我们把所有数按 \(b_i\) 分类。当 \(b_i=0\) 时可以直接暴力 dp,否则这一段里边的数要么只能给小 G,要么只能给小 W,或者不选,这也可以 dp。注意到 \(\le \sqrt{500}\) 的质因数只有 8 个,且 \(j\land k=0\),复杂度 \(\mathcal{O}(n3^8)\)

P6034 Ryoku 与最初之人笔记

注意到原条件即为 \(b-a\equiv 0\pmod {b\oplus a}\),且 \(b-a\le b\oplus a\),故 \(b-a=b\oplus a\)。直接数位 dp 即可。

P8037 [COCI2015-2016#7] Prokletnik

以左端点为最小值,右端点为最大值为例。把询问离线挂到右端点,记 \(L_i\) 表示当 \(i\) 是右端点时左端点最远到哪里,\(R_i\) 同理。考虑在左端点维护区间长度,在加入 \(a_r\) 时会把 \(R_j\ge r\)\(j\ge L_r\)\(r\) 的最远端点改成 \(r\),单调栈预处理一下直接维护即可。

P6571 [BalticOI 2017] Political Development

又不会做蓝题。

考虑部分分。当 \(d_i\le k\) 时我们可以枚举一个在团里的点,然后团里其他点只会是它相邻的点,可以 \(nk^22^k\) 算。优化就是你发现周围只有至多 10 个点,记周围的点集为 \(S\),可以 \(k^2\log n\) 预处理 \(S\) 中每个点能到达 \(S\) 中哪些点,这样单次检查复杂度变为 \(\mathcal{O}(k)\)

考虑正解。注意到还有性质没用。发现整张图一定存在至少一个点 \(d_i\le k\),那么对这个点跑上述做法后这个点就没用了,可以删去。删去后这个新图一定也有度数不超过 \(k\) 的点,直接递归做就行。

[ARC169C] Not So Consecutive

考虑 dp。记 \(f_{i,j}\) 表示填了前 \(i\) 个数,\(a_i=j\)\(a_{i-1}\neq j\) 的合法方案数,\(g_{i,j}\) 表示填了前 \(i\) 个数,\(a_i=j\) 的合法方案数。考虑转移。从 \(g_{i,j}\) 转移到 \(f_{i+1,*}\) 是简单的,思考怎么从 \(f\) 转移到 \(g\)。对于 \(g_{i,j}\),不妨枚举 \(a_i\) 所在的连续一段的长度 \(k\)\(g_{i,j}=\sum f_{i-k+1,j}\),可以前缀和转一下。复杂度 \(\mathcal{O}(n^2)\)

一点细节:比如 \(g_{i,j}\) 可以从 \(f_{i,j}\) 转移过来,而且注意到当 \([i-k+1,i]\) 内有无法变成 \(j\) 的位置时不能转移。

P3181 [HAOI2016] 找相同字符

一个提醒:如果遇到多个串之间的计数不太能做时,考虑把这些串连起来是否可做。

[ARC170C] Prefix Mex Sequence

被诈骗了。注意到我们并不真的关心当前的 mex 是多少,我们只用知道 mex 是否在 \([0,m]\) 内即可。考虑 \(f_{i,j}\) 表示前 \(i\) 个位置总共有 \(j\) 种不同的数,转移一下即可。复杂度 \(\mathcal{O}(n\min\{n,m\})\)

[ARC170D] Triangle Card Game

记三次分别选了 \(a,b,c\),考虑枚举 \(a\),思考第二个人怎么选 \(b\) 会让 \(c\) 没有可选的余地。记全集为 \(A,B\)\(c\) 的范围是 \((|a-b|,a+b)\)。注意到当 \(a\ge b\)\(b\) 越小越好,否则记 \(\text{dist}(b)=\min\limits_{c\in(A-a)}|b-c|\),如果存在 \(b\) 满足 \(\text{dist}(b)\ge a\) 则就没有 \(c\) 在范围内了。\(\text{dist}\) 是好求的,可以求最大和次大值。注意到可以不需要 \(a<b\) 这个限制,因为 \(a\ge b\)\(a-b\le 0\),这只会比真实的限制范围更大,如果这都没有 \(c\) 说明锁紧范围后仍然找不到 \(c\)。时间复杂度 \(\mathcal{O}(n\log n)\),精细实现后可以做到瓶颈在排序。

P7906 [Ynoi2005] rpxleqxq

牛的。考虑二离莫队,这是显然的,然后就不会平衡复杂度了(

正常做法就是 trie 嘛,考虑优化。一个很牛牛的想法是如果我们能把 trie 上走 \(k\)\(\mathcal{O}(1)\) 算出来那时间就是 \(\mathcal{O}(\dfrac{\log V}{k})\) 了。不妨把每个数分成前后各 9 位,加入的时候分别枚举另一个数的前 9 位或后 9 位,随便记一下就是 \(\mathcal{O}(\sqrt{V})\)\(\mathcal{O}(1)\) 查询了。

[ABC240Ex] Sequence of Substrings

堂堂复活!

今天图灵杯出了这个的强化版,不过做法差不多的。

朴素想法是设 \(f_{l,r}\) 表示结尾是 \(s[l\ldots r]\) 的最大分段数,转移就是对 \(j<l,s[i\ldots j]<s[l\ldots r]\)\((i,j)\)\(f_{i,j}+1\to f_{l,r}\)。考虑把原字符串中每个子串拉出来丢到 trie 上,这样就满足了字典序的限制,遍历的时候树状数组维护一下就行。复杂度 \(\mathcal{O}(n^2\log n)\)

注意到转移的时候 \(r-l+1\le (j-i+1)+1\),即每次最多让段长加一,因为这样显然不劣。所以段长不会超过 \(2\sqrt{n}\),复杂度 \(\mathcal{O}(n\sqrt{n}\log n)\)。可以继续把 \(\log n\) 分析掉,但我不会。

[AGC001E] BBQ Hard

原题是简单的,显然的组合意义,然后就会了。考虑加强版本,\(\sum(a_i+a_j)\le 2\times 10^7=M\)

一种想法是根号分治。称 \(a_i+b_i\le B\) 的点为小点,否则为大点。小点到小点可以沿用原来的做法,\(\mathcal{O}(B^2+n)\);大点到大点可以枚举一对点 \((i,j)\),暴力 \(\mathcal{O}(\left(\dfrac{M}{B}\right)^2)\) 算组合数;小点到大点可以先枚举大点,注意到这样从小点开始一定会经过直线 \(y=-x\) 恰好一次,不妨枚举交点 \((x,-x)\),显然 \(x\in[-B,B]\),然后小点到他的方案在小对小得时候处理过了,他到大点的方案可以直接组合数,复杂度 \(\mathcal{O}(\dfrac{M}{B}\times B)=\mathcal{O}(M)\);大点到小点类似处理。取 \(B=\sqrt{M}\) 即可 \(\mathcal{O}(M)\)

另一种想法是范德蒙德卷积。

\[\sum_{i=1}^n\sum_{j=i+1}^n{a_i+b_i+a_j+b_j\choose a_i+a_j}=\sum_{i=1}^n\sum_{j=i+1}^n\sum_x{a_i+b_i\choose a_i+x}{a_j+b_j\choose a_j-x}=\sum_x\sum_{i=1}^n\sum_{j=i+1}^n{a_i+b_i\choose a_i+x}{a_j+b_j\choose a_j-x} \]

此时前面的 \(x\) 要满足 \(x\in[-a_i,b_i]\),后面的要 \(x\in[-b_j,a_j]\),拆成两部分,开个数组存对应 \(x\) 的和,扫一遍即可。复杂度 \(\mathcal{O}(M)\)

posted @ 2023-11-05 21:12  xx019  阅读(5)  评论(0)    收藏  举报