好题分享
2025.11.7 hkx
我们考虑加入一个元素的条件,注意到限制只与元素大小关系有关,于是我们考虑论讨加入元素与之前元素的大小关系。如果我们在一个位置加入一个比它大的数那么一定是可行的。如果我们加入了一个相同的数呢?因为我们比较的是字典序,所以我们会逐位比较直到不同。我们考虑把相同的数看成一段,我们比较下一段元素的大小即可判断。能够发现我们判断的时候与段的元素大小有关而与段长无关,所以我们可以把一次添加看成在每段最后一个位置加数,这样我们就只用考虑 \(a_i>a_{i+1}\) 的限制。特殊情况就是我们还能在序列最后加数。
现在我们考虑 dp,设 \(f_{i,j}\) 表示序列长 \(i\),可用值域大小为 \(j\) 的答案,为了方便我们考虑把加数倒过来变成删数。考虑转移,因为序列中最小的元素一定是从末尾删掉的,所以我们去关注最小值,转移考虑枚举最小值位置与被删除时间,但是考虑到有多个最小值所以我们只关注最左边的那个。于是就有:
简单解释一下,系数是因为最小值被删前它后面的 \(i-p\) 个数要在前面的 \(t-1\) 次操作中被删完,然后考虑左边的区间没有了当前的最小值,右边还可以有。注意到转移中的 \(\sum\limits_{t=i-p+1}^i{t-1\choose i-p}={i\choose i-p+1}\),并且其他部分与 \(t\) 无关,所以时间复杂度 \(\mathcal O(n^3)\)。
2025.11.10 max
神秘构造题,skip。
2025.11.11 lyr
2025.11.12 orange_new
设 \(f_{i,j,k}\) 表示到 \((i,j)\) 为 \(k\) 的答案,发现最后一维状态爆炸考虑删掉无用的状态。所以这道题的关键在于如何记录较少的状态就能包含所有合法的东西,这里有一个 trick 就是乘法计入状态会爆炸于是就考虑变成除法,于是我们只会有 \(2\sqrt V\) 个不同的除数,于是直接转移就做完了。
2025.11.14
all_for_god
根号分治题。我们考虑把颜色数量大于根号的称作大块,否则称作小块。我们考虑预处理出大块对于全局的贡献。如果没有修改,此时如果询问大块我们直接查询贡献,否则我们暴力扫即可。现在考虑加入修改,如果是大块和大块的合并我们直接合并即可;如果是小块和小块的合并我们无需理会,只有当他们合成大块后我们再预处理答案;否则我们不能直接合并,因为此时的复杂度没有保证。我们可以先用并查集记一下一个块属于哪个颜色,查询的时候我们把大块小块分开查,然后再把答案合并即可。只有当多出来的小块又能变成大块的时候我们再考虑合并。
考虑每次操作都是整体减 \(d\),我们可以把每一摞砖放到数轴上考虑,每次我们就在数轴上跳。
发现如果 \(d\) 比较大我们可以较快的跳完,\(d\) 比较小的时候因为每次 \(d\) 都会减少所以操作次数不超过根号次,于是考虑值域根号分治。但是注意到可能会出现很多东西的 \(b=0\),这就导致 \(d<\sqrt n\) 的时候复杂度不能保证,此时我们尝试去处理出 \(b=0\) 的极长段,想办法快速地跳这种段。注意我们跳的限制有两个,一个是跳的一段区间没有东西了,或者是跳完了这个连续段,于是我们考虑对于 \(d<\sqrt n\) 的每个 \(d\) 去预处理第二条限制,这个可以并查集处理。然后这里的并查集并不是按秩合并所以还要多带一个 \(\log\)。
lyr
Re_Star
喵喵题。
一个思路是可以让 \(a_0,a_1\) 和 \(x,y\) 都尽量变小,如果能构造出来相同的数对那么就可以。考虑如果我们一直用减法那么序列一定唯一确定,如果有加法,可以发现我们能用 2 个减法抵消掉 1 个加法。于是加法对结果的影响就会被减法消除,所以我们一直做减法直到无法操作就能构造出最小的数对。考虑直接模拟复杂度爆炸,于是考虑辗转相除法即可。
博弈论好题。
考虑结束状态的特点:存在一个点的度数为偶数。考虑有结论:如果存在一个点的度数为偶数则先手胜,否则后手胜。要证明结论考虑构造出一种方法能让局面从“存在一个点的度数为偶数”的状态转换到“不存在一个点的度数为偶数”的状态并且后者无论如何操作都会转回去。我们考虑找到一个度数为偶数的点并满足其子树中的点度数全为奇数,这个点一定存在,如果不存在就考虑递归到子树中的偶数度数的点考虑。于是得证。
考虑没有取模我们直接大的和小的匹配,有取模的时候就不一定了。但是这个思路可以拓展,我们考虑将序列分成两半,满足前一半最小加最大小于模数,后一半最小加最大大于等于模数,此时前一半的数大的和小的匹配,后一半同理是最优的。证明可以考虑调整法。如果两部分有交一定不优,因为这样会少减去一个模数,如果各自有交显然不优。于是就做完了,找分界点可以二分。
2025.11.18 xjy
显然加法会在逻辑或后面,否则浪费的贡献一定更多,证明是显然的。然后考虑先处理逻辑或,我们肯定是让每次的损失尽量少,于是按位从高到低考虑。对于某一位,如果是 0 和 0 或起来那么无影响,否则一定会损失 1 的贡献。所以我们的策略就是先去用 0,然后再去用 1,每层都进行相同的操作,做完后将没有处理完的东西递归下去即可。
考虑一个暴力的 dp,设 \(f_i\) 表示拓展到第 \(i\) 位的最大价值,简单转移:\(f_i=\max_{j\le{i\over2}}(f_j+c_j)\),其中 \(c_j\) 表示从 \(j\) 到 \(i\) 的价值。考虑转移中有贡献的 \(c_j\) 很少,于是我们可以去找一个尽量大的 \(j\) 满足 \(c_j=1\),这样既能让当前操作做贡献,又能让 dp 值尽量大。于是我们对每个颜色考虑转移点,并找到每次的最右边的 \(j\),考虑一次操作是倍长的,所以每次操作后长度至少减半,于是有 \(n+{n\over2}+{n\over4}+\dots\le2n\),所以时间复杂度 \(\mathcal O(nq)\)。
2025.11.20 max
一道挺有意思的计数题,自己看洛谷题解不是很懂,max 讲了然后自己去看 AT 的题解就很易懂了。是好题,值得做!
首先我们可以换一种三元组的表达方式,考虑记录 \((x,a,b)\) 表示中间的点是 \(x\),其两边分别间隔 \(a,b\)。考虑变化的过程,若钦定 \(a<b\) 那么有 \((x,a,b)\to(x+a,a,b-a)\) 和 \((x,a,b)\to(x-a,b-a,a)\)。我们考虑换一种更简洁清晰的表达方式,这里我使用了 AT 的图片:

这里我们省略了 \(x\) 仅保留 \((a,b)\),然后将两种转化看成两条边,边权就是 \(x\) 的变化量。于是我们统计不同的 \((x,a,b)\) 就变成了统计从根到图上每个点的路径数,可以发现两者恰好构成双射。进一步思考,一条边上有边权,那么对于一条从根开始的路径一定对应一个边权和。那么要统计到一个点的不同路径数,就相当于是统计边权和的情况数。计数的时候需要考虑不重不漏,所以我们需要找到一种合理的统计方式,在此之前我们可以先寻找图的性质。
我们设 \(a_i\) 表示第 \(i\) 次变化时中间的点的移动距离,也就是 \(a_i\) 代表第 \(i\) 列的边的边权的绝对值。考虑这个序列一种生成方式是在做辗转相减法的过程中记录较小的数,所以可以从这方面入手寻找性质。注意到在辗转相减的过程中我们会在某段时间减去相同的值,于是考虑把 \(a_i\) 划分成 \(\mathcal O(\log V)\) 个段。假设共有 \(m\) 段,对于第 \(i\) 段,我们假设有 \(c_i\) 个 \(b_i\),现在我们在 \(b_i\) 上考虑。
这里有一个非常重要并且巧妙的性质:\(b_i=c_{i+1}\times b_{i+1}+b_{i+2}(i\le m-2)\),就比如上图中有 \(7=2\times3+1\)。等式成立的原因可以考虑用辗转相除法优化辗转相减法的时候,有 \((a,b)\to (b,a\bmod b)\),这其实就是一个被除数 \(=\) 除数 \(\times\) 商 \(+\) 余数的等式。注意这个性质在最后其实并不成立,因为最后一段的 1 全选就能凑出上一段的数,于是我们考虑手动去掉一个 1 保持性质。有了这个重要的性质之后现在考虑计数,我们先翻译一下这个结论,把它变成能够直接用的:选择了一个 \(b_i\) 等价于选择了整段的 \(b_{i+1}\) 以及一个 \(b_{i+2}\)。
那么我们考虑将所有的后者换成前者。当后者不能换成前者的时候说明第 \(i\) 段已经全选了,以此类推,前 \(i\) 段也已经全选了。说明我们一种边权和可以看成这样一种选择方案:选择了一个前缀 \(i\) 满足第一段一直到第 \(i\) 的所有数都已经全选,后面还有若干的 \(b_j\) 被选择,但是如果选择了整段的 \(b_j\) 就不能选择 \(b_{j+1}\)。
刻画出了选择方式我们就可以对此 dp 了。设 \(f_{i,0/1}\) 表示考虑到了第 \(i\) 段,在前缀全选的段不足 \(i\) 的情况下这个段是否全选。转移是简单的,但这里还是负责任地讲一下。对于 \(f_{i,0}\),考虑这一段从哪个状态转移,并且这一段选多少个数。于是有 \(f_{i,0}=f_{i-1,1}+c_i\times(f_{i-1,0}+1)\)。考虑如果上一段全选那么这一段不能选数;如果上一段不是全选那这一段可以选 \([0,c_i-1]\) 个数;如果全选的前缀是 \(i\) 那么这一段能选 \([0,c_i-1]\) 个数。对于 \(f_{i,1}\) 有 \(f_{i,1}=f_{i-1,0}\),这是显然的。
最后我们考虑统计答案。对于一段的贡献一起统计,设 \(s_i\) 表示第 \(i\) 段的答案。考虑一个段 \(i\) 最后一个位置 \(j\) 的答案为 \(f_{j,0}+f_{j,1}+1\),但是一个段中不同的位置其 \(f_{j,0}\) 是不同的,因为 \(f_{j,0}\) 与这个段的前缀长度有关。什么意思呢?就是说假设位置 \(j\) 是第 \(i\) 段的第 \(k\) 个位置,我们转移 \(f_{j,0}\) 的时候这个段能够选择的数其实只有 \([0,k-1]\),所以一个段中的 \(f_{j,0}\) 略有不同,于是统计一个段的答案的时候就不能直接写 \(c_i\times(f_{i,0}+f_{i,1}+1)\),而是去枚举段中的每个数,有:
把 \(j\) 提出来化简即可。考虑最后的答案之和,根据上图,注意到除了最后一个段其他都有两个点,然后你还要考虑不做任何操作以及开头还有两个选择,并且前面去掉的那个 1 最后还会有贡献需要加回去,于是答案为 \(3+\left(\sum_{i=1}^{m}2s_i\right)-2s_{m-2}-s_{m-1}\)。最后时间复杂度为 \(\mathcal O(q\log (c-a)\))。

浙公网安备 33010602011771号