一类做法基于变化次数的题目的总结

最近遇到不少这类题目啊,但自己像个【数据删除】一样完全没有总结经验,被花式吊打。所以痛定思痛,决定总结一下。

CF475D. CGCDSSQ

我们可以把询问离线下来,求区间 gcd 等于 x 的等价于求区间 gcd 不大于 x 的减去不大于 x1 的。考虑固定左端点,每次暴力往右拓展,这是 O(n2logn) 的。

现在,我们要用到一个结论:当你拓展的时候,区间 gcd 要么不变,要么至少缩小一半。所以你可以每次二分找到会使得 gcd 变小的那个右端点,用 ST 表维护区间 gcd,时间似乎是 O(nlognlog2A) 的,但常数极小:后面的 logA 是求 gcd 的复杂度,可以忽略不计;前面的二分也是跑不满 lognlogA 的。

CF1834E. MEX of LCM

还是那个性质:当你拓展的时候,区间 lcm 要么不变,要么至少变大一倍。第 3×105 个质数是 4256233,故我们只需要不超过 4256234 的数。

我的写法很劣,不知道为什么过不了,所以下面是 emsger 的写法。假设当前枚举到 ai,考虑开一个双端队列维护以 i 为右端点的所有可能的 lcm,同时每次把能得到的数丢进 map 里,最后求 mex 即可。优化就是如果这个双端队列是 [i,i],[i1,i][1,i] 的顺序的话,那么这些 lcm 是不减的,且一定是倍数关系。如果当前已经超过答案上限/能被 ai 整除,说明也不用看后面的了。这似乎在 ai 很小时有巨大优化。

D 【0506 B组】简单的数据结构题

发现如果我们固定一个左端点 i,因为区间变大 and 不增,且一旦变小至少会有一个 1 变为 0,那么这些区间的 and 至多有 logA 种取值。可以从右往左枚举 i,维护 posj 表示当前经过的所有 k 中,满足 akj 位为 0 的最大的 k。这样我们就在 O(nlogA+nlogAloglogA) 的时间内求出了每个 i 的 and 值的分割点(后面那个是排序 + 去重的时间)。

现在,我们把询问都离线下来,按左端点从大到小排序。从右往左枚举 i,有一些分割点把 in 分成了若干段,以 i 为左端点,同一段内的若干个下标作为右端点,得到的 and 是相同的。这样,对于每个 i,我们可以在 logA 的时间内求出哪些区间的 and 是完全平方数(因为每段中间的数一定不会影响 and 的值)。

现在,我们把那些 and 为完全平方数的区间,以右端点为下标,丢到一颗线段树上维护。对于询问 [ql,qr],我们只用查询线段树上 [ql,qr] 区间的和即可。因为我们以右端点为下标,故会对答案造成贡献的区间 [l,r] 满足 rqr。同时,枚举 i 的顺序也决定了 lql,所以这样统计是不重不漏的。

A 【0630 B组】冤

你可以假定 i[1,n],ai1

唉,被诈骗了。

因为三角形需要满足两边之和大于第三边,显然最优选法是排序后取相邻三个。考虑最坏情况,即所有长度构成斐波那契数列。因为 ai109,故长度过大的区间一定合法,剩下的暴力判断即可。

posted @   xx019  阅读(27)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示