做题记录

upd on 260727:感觉这样所有题目放在一起太乱了,尝试分类,以前的就算了。

以前

ARC 211 C

首先将连续的#.缩成一个点。 记 \(w_i\) 为每一个区间的 \(v\) 的最大值

为了将序列清空且每次只能选相邻两个.,操作次数是固定的,原序列的每一个 . 区间的 $ w_i $ 都至少被贡献过一次,而剩下的若干个能贡献进答案的数又总能是全局最大值

P14577

磁铁种类数只有 26 个,可拆开考虑每一种磁铁的贡献。

注意到每一种磁铁只有最后一个可能留下

ARC 208 A

将一堆石子拿走任意个,在二进制下本质是将某一位1改为0,之后的位随便填。

本题与 nim 游戏相通之处是,某一位1改为0确保了有一位的1数量的奇偶性必须改变。

对一串数字亦或 本质上是 看每一位上的1数量的奇偶。所以可以用亦或来指示。

CF 337 D

原先想从染色点出发将 \(dis \le d\) 的点 +1 ,于是与点分树大战。

后来发现可以求每个点到染色点的最大距离,树形DP就做完了。

原来点分树的做法也可以,不过不太熟练罢了

CF 2101 B

贪心的想,我们把奇位和偶位分开排序,可以得到最优解。唯一的问题是最后 \(a_{n-2}\)\(a_{n}\) 无法排序,也就是会让 \(a_{n-2} > a_{n}\)

看题解前止步于此

考察一次交换操作对逆序对的影响,发现 奇数位逆序对数量奇偶性的改变 与 偶数位逆序对数量奇偶性的改变 是同时发生的

\(a_{n-1}\) 所在的奇偶位逆序对数量为0,据此推出 \(a_{n}\) 所在的奇偶位逆序对数量

CF 1320 C

按武器攻击力从小到大考虑,然后思考武器攻击力变大后对每件防具的影响:

武器攻击力变大后,新增了满足怪物防御力<=武器攻击力的怪物

这些怪物可以对满足怪物攻击力 <= 防具防御力的防具造成贡献

注意到将防具排序后,受益的防具是一个[l,maxv]的区间

用线段树维护每个防具的贡献即可

P4577

看的是第一篇题解

首先参考序列上的 dp 设计,定义f[u][i]表示在 u 的子树内,大小为 i 的方案中,最小值的最大值 w


其次注意到 f[u] 单增,可以将 f[u] 由一维数组改为 multiset,集合中有多少个数比 w 大,就表示 u 代表的方案大小

之后是 dp 方程和启发式合并,详细的看题解吧

复杂度 \(O(n log^2n)\)

大概很有教育意义?复习预习了暑假没弄懂的启发式合并


将 multiset 改为权值线段树,动态开点

没有明白的点

  • 教练说可以做到单 log,但我不太会证明。但实际上跑的比 multiset 慢

  • 空间复杂度同样也不太会,开了maxn * 20就稀里糊涂地过了

  • 线段树二分部分,好像我必须记录掌管区间的最小值?好像单纯记录出现次数不太能做到单 log

ABC 447 G

link

随机化的做法以前没遇到过

ABC 450 E

严肃反思,为什么这场 ABC 发挥失常?

大概还是太浮躁了吧,思路明明是对的,只是少考虑了一种可能

更深层的原因大概是晚上勉强自己打比赛、加上上次考的太好、加上 T3 吃了一发罚时导致的

ABC450 F

赛时思路是将边排序,然后 \(dp_i\) 表示考虑前 \(i\) 条边,覆盖 \([1 , r_i]\) 的方案数,但这样定义有两重限制,假完了。

第一篇题解写的很好了,这种逐渐加边维护的技巧要学会

P4247

线段树上维护答案,合并答案容易,但维护区间加后的答案很难

原来 19940417 不是质数

P5283

也算是经典数据结构题了

将区间亦或转换为两点亦或

k *= 2补全

求两两异或的第 \(k\) 大值:从高位到低位,Trie 上贪心。记录节点大小,过程类似贪心

ABC 455 E

首先考虑容斥,要计算 AB、BC、AC、ABC 出现次数相等的串的数量。赛时想到了。

AB 出现次数相等,即 \(cnta_r - cnta_{l-1} = cntb_r - cntb_{l-1}\),即 \(cnta_r - cntb_r = cnta_{l - 1} - cntb_{l-1}\)

用 map 维护之前 \(cnta_i - cntb_i\) 每个值出现的次数即可。

至于 ABC 出现次数都相等,只要维护 \(cnta_i - cntb_i\)\(cntb_i - cntc_i\) 这个 pair 出现的次数。

关键是将式子里 \(r\)\(l - 1\) 分开到等号左右两边没有想到。这是很套路的东西。

P10590

最近好累啊,被文化课作业推着走。大脑总是昏沉,没有思考能力了。

将磁力块看作是点,A 能吸附 B 就是一条 A 到 B 的有向边。求从源点出发能到达的点有几个。BFS 即可。

接下来就是如何快速查询 A 能吸附哪些还未被吸附的点。相当于二维偏序,要满足 \(m \le p \wedge d \le r\)

排序解决一维 \(p\)\(m\),用线段树解决另一维。线段树上的节点记录区间内所有点 \(d\) 的最小值。如果当前查询的 \(r\) 大于 \(d_{min}\),说明可以吸附区间内的某个点,向下递归即可。否则返回。

稍加分析可以得到,这样的时间复杂度是 \(O(n \log n)\) 的。

P1463

数论题没做出来过。连欧拉筛都不熟悉了,待复习待复习。

抄了个欧拉筛,打出 \([1 , 10^7]\) 内的反素数,获得 70pts 的部分分。止步于此。

考虑两个数 \(a , b\)\(a < b\)。如果 \(a\) 的因数数量大于等于 \(b\),那么 \(b\) 一定不是反素数。

那么,设 \(p_i\) 为第 \(i\) 大的素数。即 \(p = [2 , 3 , 5 , 7 , 11 , ...]\)。将 \(num\) 分解。

\[num = \prod_{i = 1}^{k} p_i^{a_i} \]

那么 \(a\) 只有单调不增时, \(num\) 才可能是反素数。否则可以将后一项的指数与前一项的指数互换,因数数量不变而 \(num\) 减小了,更优。

\(a = [1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 0 , 0 , 0 , ...]\) 时,用到的素数最多,但也只有 \(10\) 个左右,爆搜就可以了。

启示,数论题不一定要探寻本质,如本题中的反素数到底是什么。只要给出一个较强的结论就行,如本题中的指数单调不增。剩下的由计算机解决。

CF915F

直接看题解,没有思考。

首先转化,把最大值与最小值拆开,这个应该能想到。

然后贡献转化,考虑每条边对答案的贡献。拆贡献应该想得到,但是把点权转化为边权以前没见过。这样的好处是边只将树分为了清晰的两部分,而不是如点一般只分成几个子树与它自身。

串串

P3546

赛时误认为第一层一定是最长的 border,瞎想了一下就这么写了。xyd 的滚木大样例全过,加上 subtask 获得了 0分:(

反例:aabaabaa,实际上答案的两层是 aaba。但我们会找到 aa。赛时不知道在想什么,这显然是没有道理的。

枚举第一层的所有 border,如何求出第二层?

\(s\) 的下标从 \(1\) 开始,记 \(s_i\) 表示 \(s[i + 1 , n - i]\)\(s_i\) 的 border 的删除第一个字符与最后一个字符一定能成为 \(s_{i + 1}\) 的 border。也就是

\[B_{s_{i + 1}} \ge B_{s_i} - 2 \]

\(B_s\) 表示 \(s\) 的最长 border。把这个式子反过来用,也就是

\[B_{s_i} \le B_{s_{i + 1}} + 2 \]

求出 \(B_{s_{i + 1}}\) 后,从 \(B_{s_{i + 1}} + 2\)\(0\) 枚举 \(p\) 看是否能成为 $B_{s_i} $。

势能分析一下,\(p\) 只会加 \(O(n)\) 次,不会减到负数,只会移动 \(O(n)\) 次。

其他串串的题

小 trick 类

P4053

考试遇到这题,想到反悔贪心但没有做出。不过我做到的版本是要在 \(T_2\) 前开始修。哎表述换一下说不定就做出来了。

限制改为在 \(T_2\) 前修好无疑是更加合理的,因为这样保证了不会影响到之后的元素。

P7165

也是几乎想出来了。设删除的边为 \(u , fa[u]\)\(v,fa[v]\),但是我没有钦定 \((u , v)\) 的顺序。这导致要统计 \((u,v)\)\((u , v)\) ,导致答案非常难以维护。钦定这个技巧太重要了呀。

还有点分治做法,赛时写出但是 corner case 写挂了。

P2414

完整版在这里。我们发现这题的输入方式使得有 \(10^5\) 个长为 \(10^5\) 的字符串,但是构建出来的 trie 树节点数只有 \(O(n)\)。这使得不能用启发式合并、线段树合并等方法做(伤心喵,都快准备开始写了发现不对劲)。合理做法是,在 trie 上访问一个节点时+1,离开时-1,这样有+1的点就是根开始的链。+1 的点在 fail 树上 +1,然后看 \(v\) 子树内权值和。发现 fail 树上的操作是单点加,求子树和,dfn 序和树状数组即可。和上一题一样,这种树上打标记的 trick 根本想不到啊。

CF822E

虽然是字符串题,但是这个 dp 居然没有想出来,太菜了,所以放在这里。\(dp_{i,j}\) 表示考虑将 s_{[1 , i]} 切成 \(j\) 段,最多能匹配到哪里。刷表法,对于 \(dp_{i,j}\),不用枚举选的下一段从哪里开始,只用考虑它的下一位是否是一段的开头。

P6640

妙妙题。二分答案规避了公共子串的右边界超过 \(r\) 的情况。

数据结构

P4396

solve1 三维数点

已经在很多题目遇到这个套路了。条件转换一下然后告诉你要满足三个条件,然后转化为三位维数点,cdq分治就做完了。

\(num_i\) 上一次出现的位置是 \(pre_i\),那么第二个答案就是满足 \(l \le i \le r,a \le num_i \le b , pre_i \le a - 1\)\(i\) 的个数。

第一问答案就是去掉第三个条件的 \(i\) 的个数。

\(l \le i \le r,a \le num_i \le b\) 不是传统的三维数点的只有一个小于,二维差分一下就好。

solve2 莫队+值域分块

看题解前想到莫队+树状数组,但是复杂度是 \(O(n\sqrt{m} \log n)\),不够好。

根据分析,莫队 \(l,r\) 指针移动了 \(n \sqrt{m}\) 次,即修改了\(n \sqrt{m}\) 次,然后查询 \(m\) 次。

树状数组失败的原因是修改与查询都是 \(O(\log n)\),这让修改的复杂度过高而查询的复杂度偏低。

改为在值域上分块,修改 \(O(1)\),而查询是 \(O(\sqrt n)\) 的。这样复杂度平衡了,过了。

ABC460F

link

P5445

link

posted @ 2025-12-18 18:47  Natho_nA  阅读(43)  评论(0)    收藏  举报