最近不会做也不想写的题

天天被吊打,搞得我都去打 Assassin's CreedCall of Duty 了。

所以就没时间写代码了


《贪心题》:给出序列 {ai} 和两个数 x,y,你每次可以给任意区间加上 ±x±y 。求最少多少次操作能使得 {ai} 变为全零。数据保证有解。n106

差分后可能的形式:只考虑前 n 个差分值,写为 di=pix+qiy 后,最小化 pi 中负数的绝对值之和与正数的绝对值之和的较大值,与 qi 的该值。

但如果考虑上第 (n+1) 个差分值,则只需最小化 |pi|+|qi| 满足 pi=0 。注:由于 di=0,此时自动有 qi=0 。这个形式是好做的。

注意到直线上 (|p|+|q|) 是关于 p凸函数,从最小值开始,选增量最优的 p0 方向调整,就是正确的。

复杂度在于最初的 pi 。注意到,根据 |x||y| 的大小关系,pi 会靠近 0di 。该差距不超过 y 。故 pi 距离 0di=0 不超过 ny 。每次调整有 y 的增量,总调整次数 O(n)


《读错题》:有全零序列 {ai} 。接下来进行 k 次操作,对于第 j 次:让每个 ai 增大 i,若其超过 hj,则令其变为 hj,且让计数器加 1 。求最后计数器的值。q 次询问不同的 k 。其中 {hi} 有长度为 m 的循环节。n,m,q3×105h 非负。

关于题读错了还津津有味地跟蛋神讨论这件事

任意时刻 ai 不降,因此每次使得计数器加 1 的是段后缀。而且,若 ait 时刻有贡献,则其在 (t+m) 时刻有贡献——若中途有太小的 hκ 使得 (t+m) 时刻不贡献,则 hκm 同样能使得 t 时刻不会有贡献。

注:若 κ<m,则 0 时刻 ai=0 相当于更强的限制。这是 h0 的好处。

所以 ai 在其首次被赋值后,值在周期性变化。设首次赋值时间为 t,只需求解 [t,t+m) 单个 循环节 的贡献即可。

考虑计算每个 i 的贡献。在 i 从小变大时,始终保留单循环节的贡献,动态加入新的可贡献时间。总共只有 O(m) 次加入,复杂度是正确的。

于是问题有二:求首次贡献的时间;其后在循环节内,哪些时间有贡献。

前者易求:设 hκ 首次赋值 ai 在第 t 轮,则 (tm+κ)ihκ,移项得 t 关于 i 的直线方程——尽管带有上取整,其大小关系仍只会变化一次,因为上取整是几乎保序的。又考虑到 κ 小的优先,则只有严格不等号,可以用李超树维护,或直接建立凸包求解。

后者在枚举 i 时求解是困难的。但其实 hκ 是否有贡献,跟当前的 t 关系不大——反正是循环的,可以想象成求解无穷远处的 hmω+κ 是否有贡献。

因此只需其余数字不限制自己。以 κ=m 为例,只需 minj=1k1{hj+(κj)i}>hκ 即可。

不难发现这等价于 i>max{hκhjκj} 。枚举 κ 后,维护凸包可以 O(logm)RHS 。因此就得到了每个 κ 的加入时间。

考虑询问。二分得到极长后缀 p 使得其在 k 时间内至少被赋值一次,把询问放在 p 上。改为 i 从大到小枚举,将其对不同的 kmodm 的贡献累加起来。这可以用线段树历史和。顺便得到 km 的系数。则每个询问可以 O(logm) 出结果。

总复杂度 O(qlogn+qlogm+mlogm+n)


《Codechef Xor Matrix》

时至今日,尚不能完全理解,只能破碎地、模糊地给出些猜想。蛋神题解极其简略,我不能懂其分毫。

考虑 +1 的作用:反转该数的较低的 bit 位。那么目标就是不断加减 x,y 使得其反转作用和 0 自加到 k 的反转作用相同。

考虑基本单位 Ak[0,2k) 内的数之间的反转作用,即长为 (2k1) 的数列。A0=,Ak={Ak1,k1,Ak1},其中数字 (k1) 表示 2k1 以及更低的 bit 被反转了。

把询问区间拆解得到 {Alα,,l2,Al2,l1,Al1,m,Ar1,r1,Ar2,r2,,Arκ},满足 lα<<l2<l1<mm>r1>r2>>rκ

答案显然为 2max{l1,r1}+1,不妨设 r1l1,因为可以 xAr1,r1yAr1 完成 Ar1+1 同步,而 (r1+1) 的缺席表明这是最大的。特别地,若 m=r1+1,根据下面对方案数的讨论可知,不可能使用之。

方案数呢?两侧对称,以右侧为例。若起点在 Ar1 的空隙中,由于其中之一需靠近 r1,问题变为,有多少种方案,从 Ak 中相同位置出发,走出 Ak 的序列,且结束时某个 pointer 在边缘。

定理:上述路径对每个起点都唯一存在,且结束时两个 pointer 在异侧边缘。

首先证明引理是,单个 pointerAk 边缘出发,走出 Ak,唯一方案是走到另一边缘。该引理不难用归纳法证明。

有了引理,该定理不难用归纳法证明。因此随便一个起点都能完成任务。

接下来 x 紧靠着 Ar1y 靠着 Ar2,需要走出 Ar1 序列。每次讨论需要走出的 max 由谁提供,可以将 r1,r2 不断推进。它的方案数应该可以 O(κ) 计算,应该吧(因为状态会落到 r1=r2 的位置)。

然而起点在 Ar2 的空隙中是不可行的。因为那需要 x 一直停在 r1 旁边,等待 y 走出 Ar1,而 y 是做不到这一点的,因为右边没有充分的原料。想要利用 m=r1+1 和该情况本质相同:都是不可实现的。

所以我们每组询问是 O(α+κ)=O(logR) 解决的。


《让我当小丑题》:给棵树,每个节点上有石子,在上面玩游戏,每次将单个石子移动至子树内,不可操作者负。动态增删单点石子,并询问与 x 相邻的点中,有哪些点满足:以其为根时,即使后手能在树上任意节点多放一个石子,先手仍然必胜。n106

我是大小丑,请问我究竟是大还是小

注意到 sg 值就是最长链的长度(边数)。每个点为根时,游戏的 sg 值容易用 dfs 序上的线段树维护。而 后手能放石子就是能放 height 以内的值没想到吧,我没发现这个)。

于是问题变为,哪些点的游戏 sg 值大于 height

不要泛化,考虑 sg 的特点:儿子节点的 sg 值可以由 ai 异或 v 得到,其中 v 是对每个子节点都相同的,而 ai 可以对每个节点预处理得到。

因此对所有子节点,问题相当于是,给定 w[aiw>bi] 。在 trie 树上可以 O(logmax{a,b})=O(logn) 查询。

注:事实上,对于短儿子,它们的 heightbi 是相同的。但这不能优化复杂度,所以就没什么了。

父节点可以暴力,总复杂度 O(nlogn)

posted @   OneInDark  阅读(109)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
点击右上角即可分享
微信分享提示