最近不会做也不想写的题
天天被吊打,搞得我都去打 \(\text{Assassin's Creed}\) 和 \(\text{Call of Duty}\) 了。
所以就没时间写代码了。
《贪心题》:给出序列 \(\{a_i\}\) 和两个数 \(x,y\),你每次可以给任意区间加上 \(\pm x\) 或 \(\pm y\) 。求最少多少次操作能使得 \(\{a_i\}\) 变为全零。数据保证有解。\(n\leqslant 10^6\) 。
差分后可能的形式:只考虑前 \(n\) 个差分值,写为 \(d_i=p_ix+q_iy\) 后,最小化 \(p_i\) 中负数的绝对值之和与正数的绝对值之和的较大值,与 \(q_i\) 的该值。
但如果考虑上第 \((n{+}1)\) 个差分值,则只需最小化 \(\sum|p_i|+\sum|q_i|\) 满足 \(\sum p_i=0\) 。注:由于 \(\sum d_i=0\),此时自动有 \(\sum q_i=0\) 。这个形式是好做的。
注意到直线上 \((|p|{+}|q|)\) 是关于 \(p\) 的 凸函数,从最小值开始,选增量最优的 \(p\) 往 \(0\) 方向调整,就是正确的。
复杂度在于最初的 \(\sum p_i\) 。注意到,根据 \(|x|\) 和 \(|y|\) 的大小关系,\(p_i\) 会靠近 \(0\) 或 \(d_i\) 。该差距不超过 \(y\) 。故 \(\sum p_i\) 距离 \(\sum 0\) 或 \(\sum d_i=0\) 不超过 \(ny\) 。每次调整有 \(y\) 的增量,总调整次数 \(\mathcal O(n)\) 。
《读错题》:有全零序列 \(\{a_i\}\) 。接下来进行 \(k\) 次操作,对于第 \(j\) 次:让每个 \(a_i\) 增大 \(i\),若其超过 \(h_j\),则令其变为 \(h_j\),且让计数器加 \(1\) 。求最后计数器的值。\(q\) 次询问不同的 \(k\) 。其中 \(\{h_i\}\) 有长度为 \(m\) 的循环节。\(n,m,q\leqslant 3\times 10^5\) 且 \(h\) 非负。
关于题读错了还津津有味地跟蛋神讨论这件事。
任意时刻 \(a_i\) 不降,因此每次使得计数器加 \(1\) 的是段后缀。而且,若 \(a_i\) 在 \(t\) 时刻有贡献,则其在 \((t{+}m)\) 时刻有贡献——若中途有太小的 \(h_\kappa\) 使得 \((t{+}m)\) 时刻不贡献,则 \(h_{\kappa-m}\) 同样能使得 \(t\) 时刻不会有贡献。
注:若 \(\kappa<m\),则 \(0\) 时刻 \(a_i=0\) 相当于更强的限制。这是 \(h\geqslant 0\) 的好处。
所以 \(a_i\) 在其首次被赋值后,值在周期性变化。设首次赋值时间为 \(t\),只需求解 \([t,\;t{+}m)\) 单个 循环节 的贡献即可。
考虑计算每个 \(i\) 的贡献。在 \(i\) 从小变大时,始终保留单循环节的贡献,动态加入新的可贡献时间。总共只有 \(\mathcal O(m)\) 次加入,复杂度是正确的。
于是问题有二:求首次贡献的时间;其后在循环节内,哪些时间有贡献。
前者易求:设 \(h_\kappa\) 首次赋值 \(a_i\) 在第 \(t\) 轮,则 \((tm+\kappa)\cdot i\geqslant h_\kappa\),移项得 \(t\) 关于 \(i\) 的直线方程——尽管带有上取整,其大小关系仍只会变化一次,因为上取整是几乎保序的。又考虑到 \(\kappa\) 小的优先,则只有严格不等号,可以用李超树维护,或直接建立凸包求解。
后者在枚举 \(i\) 时求解是困难的。但其实 \(h_\kappa\) 是否有贡献,跟当前的 \(t\) 关系不大——反正是循环的,可以想象成求解无穷远处的 \(h_{m\cdot\omega+\kappa}\) 是否有贡献。
因此只需其余数字不限制自己。以 \(\kappa=m\) 为例,只需 \(\min_{j=1}^{k-1}\{h_j+(\kappa{-}j)\cdot i\}>h_\kappa\) 即可。
不难发现这等价于 \(i>\max\{\frac{h_\kappa-h_j}{\kappa-j}\}\) 。枚举 \(\kappa\) 后,维护凸包可以 \(\mathcal O(\log m)\) 求 \(\rm RHS\) 。因此就得到了每个 \(\kappa\) 的加入时间。
考虑询问。二分得到极长后缀 \(p\) 使得其在 \(k\) 时间内至少被赋值一次,把询问放在 \(p\) 上。改为 \(i\) 从大到小枚举,将其对不同的 \(k\bmod m\) 的贡献累加起来。这可以用线段树历史和。顺便得到 \(\lfloor{k\over m}\rfloor\) 的系数。则每个询问可以 \(\mathcal O(\log m)\) 出结果。
总复杂度 \(\mathcal O(q\log n+q\log m+m\log m+n)\) 。
《Codechef Xor Matrix》
时至今日,尚不能完全理解,只能破碎地、模糊地给出些猜想。蛋神题解极其简略,我不能懂其分毫。
考虑 \(+1\) 的作用:反转该数的较低的 \(\rm bit\) 位。那么目标就是不断加减 \(x,y\) 使得其反转作用和 \(0\) 自加到 \(k\) 的反转作用相同。
考虑基本单位 \(A_k\) 为 \([0,2^k)\) 内的数之间的反转作用,即长为 \((2^k{-}1)\) 的数列。\(A_0=\varnothing,\;A_k=\{A_{k-1},\;k{-}1,\;A_{k-1}\}\),其中数字 \((k{-}1)\) 表示 \(2^{k-1}\) 以及更低的 \(\rm bit\) 被反转了。
把询问区间拆解得到 \(\{A_{l_\alpha},\dots,l_2,A_{l_2},l_1,A_{l_1},m,A_{r_1},r_1,A_{r_2},r_2,\dots,A_{r_\kappa}\}\),满足 \(l_\alpha<\cdots<l_2<l_1<m\) 且 \(m>r_1>r_2>\cdots>r_\kappa\) 。
答案显然为 \(2^{\max\{l_1,r_1\}+1}\),不妨设 \(r_1\geqslant l_1\),因为可以 \(x\) 走 \(A_{r_1},r_1\) 后 \(y\) 走 \(A_{r_1}\) 完成 \(A_{r_1+1}\) 同步,而 \((r_1{+}1)\) 的缺席表明这是最大的。特别地,若 \(m=r_1+1\),根据下面对方案数的讨论可知,不可能使用之。
方案数呢?两侧对称,以右侧为例。若起点在 \(A_{r_1}\) 的空隙中,由于其中之一需靠近 \(r_1\),问题变为,有多少种方案,从 \(A_k\) 中相同位置出发,走出 \(A_k\) 的序列,且结束时某个 \(\rm pointer\) 在边缘。
定理:上述路径对每个起点都唯一存在,且结束时两个 \(\rm pointer\) 在异侧边缘。
首先证明引理是,单个 \(\rm pointer\) 从 \(A_k\) 边缘出发,走出 \(A_k\),唯一方案是走到另一边缘。该引理不难用归纳法证明。
有了引理,该定理不难用归纳法证明。因此随便一个起点都能完成任务。
接下来 \(x\) 紧靠着 \(A_{r_1}\) 而 \(y\) 靠着 \(A_{r_2}\),需要走出 \(A_{r_1}\) 序列。每次讨论需要走出的 \(\max\) 由谁提供,可以将 \(r_1,r_2\) 不断推进。它的方案数应该可以 \(\mathcal O(\kappa)\) 计算,应该吧(因为状态会落到 \(r_1=r_2\) 的位置)。
然而起点在 \(A_{r_2}\) 的空隙中是不可行的。因为那需要 \(x\) 一直停在 \(r_1\) 旁边,等待 \(y\) 走出 \(A_{r_1}\),而 \(y\) 是做不到这一点的,因为右边没有充分的原料。想要利用 \(m=r_1+1\) 和该情况本质相同:都是不可实现的。
所以我们每组询问是 \(\mathcal O(\alpha+\kappa)=\mathcal O(\log R)\) 解决的。
《让我当小丑题》:给棵树,每个节点上有石子,在上面玩游戏,每次将单个石子移动至子树内,不可操作者负。动态增删单点石子,并询问与 \(x\) 相邻的点中,有哪些点满足:以其为根时,即使后手能在树上任意节点多放一个石子,先手仍然必胜。\(n\leqslant 10^6\) 。
我是大小丑,请问我究竟是大还是小?
注意到 \(sg\) 值就是最长链的长度(边数)。每个点为根时,游戏的 \(sg\) 值容易用 \(\rm dfs\) 序上的线段树维护。而 后手能放石子就是能放 \(\rm height\) 以内的值(没想到吧,我没发现这个)。
于是问题变为,哪些点的游戏 \(sg\) 值大于 \(\rm height\) 。
不要泛化,考虑 \(sg\) 的特点:儿子节点的 \(sg\) 值可以由 \(a_i\) 异或 \(v\) 得到,其中 \(v\) 是对每个子节点都相同的,而 \(a_i\) 可以对每个节点预处理得到。
因此对所有子节点,问题相当于是,给定 \(w\) 问 \(\sum[a_i\oplus w>b_i]\) 。在 \(\tt trie\) 树上可以 \(\mathcal O(\log\max\{a,b\})=\mathcal O(\log n)\) 查询。
注:事实上,对于短儿子,它们的 \(\rm height\) 即 \(b_i\) 是相同的。但这不能优化复杂度,所以就没什么了。
父节点可以暴力,总复杂度 \(\mathcal O(n\log n)\) 。
如果这篇文章对你有帮助,那么作者是:OneInDark,原文在:https://www.cnblogs.com/OneInDark/p/16545496.html,否则我也不知道这是谁的文章。