若干 trick

若干 trick

CF 570D

一棵树,每个节点上有一个字母,每次查询点 xy 级儿子的字母是否能重排成一个回文串。

trick:压位,只有01的信息(在此题中是奇偶性),可以压成一个 int 来并行计算,这样就可以砍掉一个 log

用到类似trick的题:由乃的OJ

ARC 127C

给定 N,X,要求在 [1,2N1] 的范围内找字典序排名第 X 小(没有前导零)的二进制数,其中 X 是以 2 进制给出的。

首先先假装 0 存在,这个是不要紧的,令 XX1

然后数可以分成三类,010 开头的,11 开头的,如果 X=0,那么答案就是 0;否则,若 1X<2N1,那么就是 10 开头,然后令 XX10 没有了),若 X>2N1,说明是 11 开头,X 减去 2N1 即可。

由于每次减去 2N1 的话是砍掉最高位可以 O(1),然后 1 的话就暴力借位,对于每一位考虑最劣情况下借位次数,其数量是 n2i=O(n)

trick:对于一个数,每次只有 +1,或者每次只有 1,暴力进位/借位次数均摊下来是 O() 的。

AGC 052B

给定一棵树,每条边有一个初始边权和一个要得到的边权,每次可以选择一条边 (u,v,w),令这条边的所有邻边的权值都异或 w

考虑边权转点权,让边权满足其为相邻点权的异或和,操作变成交换两个点的点权。

随便钦定一个为根,设 di 为初始时 i 的点权,fii 期望得到为多少。如果存在 d,f,满足它们是相同的集合,就有解。

注意到如果确定了一个点的点权,那么其他所有点权都能唯一的确定。

现在钦定 fii 到根路径上的边权和(或者说钦定 f1=0),注意到任何一组解都能把所有点权异或 f1,得到 f1=0 的解,所以判断是否有解就判断 f1=0 的时候是否有解。

现在 f 确定了,看是否存在 d,满足 df 是相同的集合。

现在继续钦定 dii 到根路径上边权和,与 f 相同,所有可能为答案的 d 都是 d 异或上一个 x 得到的。

那么有解的充分条件就是 (d1x)(d2x)...(dnx)=f1f2...fn,由于 n 为奇数,所以可以解出 x 是多少。

由于这仅是充分条件,那么最后还要 check 一下是否合法。

trick:由充分(或者必要)条件可以得出答案可能的一种或多种取值,然后暴力判断必要(或者充分)条件是否满足。

AGC 045B

有个 01 序列,其中有些位置不确定。要确定这些位置,最小化区间 01 出现次数的差的绝对值的 max

作一下前缀和,问题变成使得前缀和的极差尽可能小。先考虑暴力怎么做是不是加边加边并查集,枚举前缀和 s 的最大值,然后从前往后贪心想使得最小值尽可能大,如果当前能填 +1 就填 +1,否则填 1

观察这个贪心,考虑到枚举的 s 的最大值 +2 之后,最多有一个 1 变成了 +1,因为上界 +2 后又 2,所以从那个位置之后的填法和之前是一样的。所以最大值 +2 之后,最大的最小值最多会 +2,故不会更优。

所以只枚举可能的最小的前缀和最大值及其 +1 即可。

trick:先考虑暴力怎么做,然后给暴力剪枝/优化

ARC 128A

初始有 1 黄金和 0 白银,接下来 n 天,在第 i 天可以选择什么也不做,或者把 x 黄金换成 x×Ai 白银,把 x 白银换成 x/Ai 黄金。构造方案使得最终得到黄金最大。

假设现在有 x 克金子如果在第 i 天将金子换成银子,紧接着在第 j 天把银子换成金子,那么 xx×AiAj

  • 把限制松一松,一天可以交换多次,发现和原问题等价,交换两次相当于没有交换。
  • 把限制紧一紧,一次对换,即在第 i 天将金子换成银子,紧接着在第 j 天把银子换成金子。仅允许 i+1=j .发现和原问题等价,i 天金到银,j 天银到金,等价于 i 天金到银,i+1 天银到金,i+1 天金到银,i+2 天银到金...j 天银到金。即 (i,j) 对换,等价于 (i,i+1),(i+1,i+2),...,(j1,j) 对换。

问题转化成让 1 克金子,每次可以乘上 AiAi+1,所以只有 Ai>Ai+1 的时候,才选择对换 (i,i+1)

对应回原问题,一笔交易被对换奇数次才相当于做这一笔交易。

trick:限制松一松/紧一紧发现和原问题等价。

Code

思维不好怎么办?第一眼可以看出暴力 dp,设 fi,0/1 代表在做完前 i 笔交易,手里拿的金子/银子的最大克数,转移的时候判断大小,用 log 来比较就可以。对应了[Code+#4]组合数问题2这道题的 trick数比较大且运算只有乘除法/次方的时候用 log 比较大小。

CF 506D

给定一张无向图,每次询问给定 u,v,求有多少 c 满足至少存在一条 uv 的路径,其颜色均为 c

想不出来的时候就想暴力,然后优化优化,然后尝试平衡复杂度(虽然这题没有把两个暴力拼起来平衡复杂度)

对于每一个颜色开个并查集,会用到的点数只有 2m 个。

然后对于一个询问 (u,v),对其中一个点出边的颜色所在的并查集,看 u,v 是否连通,由于 u,v 是等价的,所以查询度数 d 较小的那一边。

如果一个询问询问了多次,可以直接用之前已经得出的答案。

这个复杂度是有理有据的,对于 d>2m 的点,最多有 2m 个,查询的复杂度为 O(2m×2m×2m)=O(mm)

对于 d<m 的点,最多查询 q 次,查询的复杂度为 O(qm),如果把并查集的复杂度看成常数的话总复杂度就是 O((m+q)m)

应该还有其他拼暴力的方法,但这个一个暴力就够了。

CF 383E

给出 n 个长度为 3 的由小写字母组成的单词,一个单词是正确的当且仅当其包含至少一个元音字母。这里的元音字母是 a 到 x 的一个子集。对于所有元音字母集合,求这 n 个单词中正确单词的数量平方的异或和。

设总有效字符数为 m=24

对于一个集合而言,答案为 包含其中一个字母的单词数 同时包含两个字母的单词数 + 同时包含三个字母的单词数。

同时包含三个字母的单词数就是完全包含在集合中的单词数,做个高维前缀和就可以了。复杂度 O(2mm)

只看前两项,fS 为集合元音字母集合为 S 时的答案,从 fSlowbit(S) 转移而来。复杂度 O(2mm)

有更简单做法:

经典套路正难则反:与集合有交的集合数 = 总集合数 与集合不相交集合个数 = 总集合数 其补集的子集出现次数。

这样一遍高维前缀和就ok了。

CF 715C

给定一棵树,边权 1w9。给定一个数 M,保证 gcd(M,10)=1

对于一对有序的不同的顶点 (u,v),他沿着从顶点 u 到顶点 v 的最短路径,按经过顺序写下他在路径上遇到的所有数字(从左往右写),如果得到一个可以被 M 整除的十进制整数,那么就认为 (u,v) 是有趣的点对。

求有趣的对的数量。

树上满足某种条件的路径个数要想到点分治

点分治,对于一个分治中心,求出子树中每个节点自上而下的数字 d1(modm),匹配上另一个自下而上的数字 d2(modm),其深度为 k,要满足 d2+d1×10k0(modm)d2×10k+d10(modm),((m,10)=1),开个 map 统计就可以了。时间复杂度 2log(map)或者 1log(unordered_map

CF 555E

给定一张 n 个点 m 条边的无向图和 q 组点对 (s,t),现在要给每条边定向成有向图。

询问是否存在一种定向方案使得所有 s 都能到达 t

点对之间是否存在可达路径 Tarjan(不要想支配树了啊喂你又不会建支配树)

按照边双缩个点,缩出来一棵树。一个边双内的点对肯定能互相到达,连出来一个环就可以。现在只有边双之间的点对,看看是否能满足所有的 st,随便钦点一个根,有边既要朝向根又要朝向叶子就不合法,用个树上差分解决。

自己瞎编的边差分竟然是麻烦了,点权代表点和父亲的边权,边差分作子树和更好写。

posted @   do_while_true  阅读(57)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?

This blog has running: 1845 days 1 hours 33 minutes 26 seconds

点击右上角即可分享
微信分享提示