有意思的题——做题记录
从 2026.3.26 开始写,记录一些有意思的题目。
P3641 [APIO2016] 最大差分
考虑先花 \(n + 1\) 的代价找到 \(a_1,a_n\)。
那么显然 \(\max(a_i - a_{i-1})\ge \frac{a_n - a_1}{n- 1}\)。那么值域上每 \(\frac{a_n-a_1-1}{n-1}\) 分一段,显然最后答案只会是不同段之间的差值最大值。这样一共有 \(O(n)\) 段,每个数一定会被查 \(1\) 次,算上之前的代价就是 \(3n\) 的。
AT_agc013_d [AGC013D] Piling Up
考虑取一次对两种颜色的影响。记 \(c\) 为红色的数量,那么 \(n-c\) 为蓝色的数量。记 \(R\) 为红色,\(B\) 为蓝色。
- \(RR\)。\(c \to c-1\)。要求之前 \(c \ge 1\)。
- \(RB\)。\(c \to c\)。要求之前 \(c \ge 1\)。
- \(BR\)。\(c \to c\)。要求之前 \(c \le n-1\)。
- \(BB\)。\(c \to c + 1\)。要求之前 \(c \le n-1\)。
不妨令初始时 \(c =0\),那么可以按照上面的操作得到 \(h_i\) 表示执行完第 \(i\) 轮后 \(c\) 的值。那么对于一个最终合法的 \(c_0\),应该满足:
- 对于所有 \(R*\) 操作的 \(i\),有 \(h_i + c_0 \ge 0\)。这里本来应该是 \(\ge 1\),但是执行 \(c \to c-1\) 后就变成 \(0\) 了。
- 对于所有 \(B*\) 操作的 \(i\),有 \(h_i + c_0 \le n\)。同上。
分情况讨论:
- 存在 \(R*\) 操作且 \(h_i < 0\)。那么此时如果该方案合法一定存在一个 \(c_0\)(也是最小的)使得 \(\min(h_i) + c_0 =0\)。这里 \(\min(h_i)\) 表示的是 \(R*\) 操作的 \(h\) 最小值。
- 不存在 \(R*\) 操作且 \(h_i < 0\)。此时直接让 \(c_0=0\) 一定合法。
那么这样就可以对所有方案构造映射了,有 \(f(G) = c_0\),其中 \(c_0\) 是最小可行的值。考虑分两类计数。
-
对于情况 \(1\)。维护 \(f_{i,j,0/1}\) 表示当前执行完前 \(i\) 轮操作,\(c = j\),且是否存在 \(R*\) 操作且 \(h_i + c_0 = 0\)。那么:
\[f_{0,c_0,0} = 1[1 \le c_0 \le n]\\ \]-
\[f_{i, j - 1,0}\gets f_{i - 1,j,0}[j > 1] (R)\\ f_{i,j-1,1}\gets f_{i - 1,j,0} [j = 1] (R)\\ f_{i,j - 1,1}\gets f_{i - 1,j,1} [j \ge 1] (R)\\ f_{i, j,0/1}\gets f_{i-1,j,0/1} [j \le n-1](B)\\ \]
-
\[f_{i,j + 1,0/1}= f'_{i,j,0/1} \]
-
\[f_{i, j - 1,0}\gets f'_{i,j,0}[j > 1] (R)\\ f_{i,j-1,1}\gets f'_{i,j,0} [j = 1] (R)\\ f_{i,j - 1,1}\gets f'_{i,j,1} [j \ge 1] (R)\\ f_{i, j,0/1}\gets f'_{i,j,0/1} [j \le n](B)\\ \]
最后答案就是 \(\sum f_{m,j,1}\)。复杂度 \(O(nm)\)。
-
-
对于情况 \(2\)。定义同上。有:
\[f_{0,0} = 1 \]-
\[f_{i,j - 1}\gets f_{i-1,j} [j \ge 1](R)\\ f_{i,j}\gets f_{i-1,j} [j \le n-1](B) \]
-
\[f_{i,j+1}= f'_{i,j} \]
-
\[f_{i,j - 1}\gets f'_{i,j} [j \ge 1](R)\\ f_{i,j}\gets f'_{i,j} [j \le n](B) \]
答案为 \(\sum f_{m,j}\)。时间复杂度 \(O(nm)\)。
-
最后把两个加起来就行了。
其实可以合一起,第二个相当于初始化 \(f_{0,0,1}=1\)。
AT_agc002_f [AGC002F] Leftmost Ball
考虑判断一种方案是否合法。应该满足对于任意前缀 \(1\sim i\),都有 \(0\) 的数量不小于颜色数量,且最后每种颜色恰好出现了 \(k-1\) 次。
考虑定义两种方案本质相同,当仅当 \(0\) 的位置相同,且出现位置集合构成的集合相同。比如 \(0012\) 和 \(0021\) 是相同的。那么我们就只需要求有多少本质不同的方案,再乘上 \(n!\) 即可。
此时第 \(i\) 个 \(0\) 可以直接视为颜色 \(i\) 的开头。那么就可以用插入的方式生成序列了。具体的,定义 \(f_{i,j}\) 表示插入完颜色 \(1 \sim i\),且 \(i\) 这个颜色 \(0\) 的位置在 \(j\) 的方案数。则我们只需要保证插入 \(i + 1\) 这个颜色后颜色第一次出现的位置在 \(j\) 后面即可。有:
前缀和优化即可。最后答案就是 \(n!\sum f_{n,i}\)。但是时间复杂度是 \(O(n^2K)\) 的。
换个角度,不看做是在插入,而是看做确定位置。那么如果已知颜色 $1\sim i $ 占了哪些位置,一定可以知道 \(i+1\) 的开头在哪里,也就是第一个还没被占的位置。那么对于剩下 \(K-1\) 个数,剩余位置有 \(n\times K - i \times K - 1\) 个。所以可以定义 \(f_i\) 表示前 \(i\) 个颜色的方案数,则 \(f_i = f_{i-1}\times \binom{(n-(i-1))\times K - 1}{K -1}\)。答案仍然是 \(n!\sum f_{n}\)。复杂度 \(O(n^2)\)。瓶颈在于组合数。
发现过不了样例,问题在于 \(0021\) 是不应该被计算的(和他本质相同的是 \(0012\)),但插入 \(1\) 的时候选择 \(1,4\) 位置就使得它被计算了。
此时应该再添加一个限制:对于任意颜色 \(i\),它前两次出现的位置 \(p_1,p_2\) 中间不能存在 \(j >i\),使得 \(j\) 出现至少 \(2\) 次。
那么可以定义 \(f_{i,j}\) 表示前 \(i\) 个颜色填完,当前第一个空往后数 \(j\) 空位都有这个限制的方案数。那么枚举 \(i\) 这个颜色放在第几个空位,有:
前缀和优化即可,由于最后答案为 \(n! f_{n,0}\),所以第二位是 \(O(n)\) 量级的。时间复杂度 \(O(n^2)\)。
P3447 [POI 2006] KRY-Crystals
考虑对于每个 \(i\),找到最大的 \(j\),使得 \(a_i\) 和 \(m_i\) 第 \([j,31]\) 位相同。
记 \(j\) 最大的那个下标为 \(i_0\),且对应的 \(j\) 为 \(j_0\)。那么如果 \(\bigoplus \limits_{i=1}^{n}a_i =0\),一定有对于 \(j \in [j_0,31]\),\(\bigoplus\limits_{i=1}^{n}m_{i,j} =0\)。
显然,\(m_{i_0,j_0 - 1} = 1\) 且 \(a_{i_0,j_0-1}=0\)。对于 \([0,j_0 - 2]\) 这些位,由于 \(a_{i_0}\) 是可以取到 \([0,2^{j_0-1}-1]\) 的,所以对于 \([1,i_0)\cup (i_0,n]\) 中所有数,无论它们值是多少,都是可以对应唯一的 \(a_{i_0}\) 的,因为在不管 \([j_0-1,31]\) 这些位时,\(\bigoplus \limits_{i\ne i_0}^{}a_i = a_{i_0}\)。则现在只需要考虑 \(j_0 - 1\) 这一位异或和为 \(0\) 的情况了,不是直接判断 \(\bigoplus\limits_{i=1}^{n}m_{i,j_0-1}\) 的原因是可能有多个 \(i\) 对应的 \(j\) 是 \(j_0\),此时应该异或 \(0\) 而不是 \(1\)。
枚举 \(j_0 - 1 = x\)。定义状态函数 \(f_{i,0/1,0/1}\) 表示前 \(i\) 个数,当前异或和为 \(0/1\),不存在或存在一个 \(i_0\) 对应的 \(j\) 是 \(x+1\) 的价值和。
- \(m_{i,x} = 0\)。\(f_{i,j,k} = f_{i-1,j,k} \times (1 + (m_i \& (2^{x} - 1)))\)。
- \(m_{i,x} = 1\)。
- \(a_{i,x} = 1\)。\(f_{i,j,k} \gets f_{i-1,j\oplus 1,k} \times (1 + (m_i \& (2^{x} - 1)))\)。
- \(a_{i,x} = 0\)。
- 之前不存在这样的 \(i_0\)。\(f_{i,j,1}\gets f_{i-1,j,0}\)。
- 之前存在这样的 \(i_0\)。\(f_{i,j,1}\gets f_{i-1,j,1} \times 2^x\)。
最后答案就是 \(f_{n,0,1}\)。时间复杂度 \(O(n\log V)\)。
P10104 [GDKOI2023 提高组] 异或图
如果 \(m = 0\),那就是 P3447。只需要添加一个 \(a_{n+1}\),差分一下。复杂度是 \(O(n\log V)\) 的。
如果 \(m \ne 0\),尝试容斥。我们去钦定一些边不合法,记边集为 \(S\)。这样可以以 \(O(n\log V)\) 的时间复杂度算出 \(g(S)\) 表示 \(S\) 中的边一定不合法时的方案数。要求 \(f(\emptyset)\)。显然,容斥系数应该是 \((-1)^{|S|}\)。有 \(f(\emptyset) = \sum\limits_{S \subseteq E}^{} (-1)^{|S|}g(S)\)。但是 \(m \le \frac{n(n-1)}{2}\)。
考虑钦定一些点相同,对于一个联通块 \(U\),它会对所有满足通过边集 \(S\) 连接能够得到 \(U\) 的 \(S\) 产生贡献,且贡献是一定的。那么 \(U\) 的容斥系数就可以是 \(\sum\limits_{S}^{}(-1)^{|S|}\)。
考虑维护 \(h_U\) 表示 \(U\) 集合中的点联通时容斥系数的和。
因为对于 \(U\) 中点都相同的情况,我们最终的限制应该是 \(a = \min\limits_{x\in U}^{} a_x\)。不妨将 \(a\) 升序排序。定义状态函数 \(f_{S,s}\) 为现在集合中点集为 \(S\),且有限制的点集为 \(s\) 的贡献和。考虑去枚举新加进来的集合 \(U\) 的 lowbit,记为 \(i\)。那么有转移方程:
这里有两种转移方程是因为如果钦定偶数个数值相同,异或一定是 \(0\)。这部分枚举量是 \(\sum\limits_{i=1}^{n}3^{n-i}2^i\) 也就是 \(O(3^nn)\) 级别的。因为 \([1,i-1]\) 一定已经在 \(U'\) 中,是不需要枚举的,只需要在意 \([i + 1,n]\) 哪些数在 \(U'\),哪些数在 \(U\)。
对于答案,就是 \(\sum\limits_{s}^{}f_{U,s} \times w(s)\),其中 \(w(s)\) 为只有 \(s\) 中的点产生限制时的方案数。这部分时间复杂度 \(O(2^nn\log V)\)。
\(h_U\) 的计算是相对容易的。依旧考虑容斥,首先 \(h_{U} = \sum \limits_{S}^{} (-1)^{|S|}\),记 \(E(U)\) 为原图上 \(u \in U\land v\in U\) 的边的数量,那么 \(h_U = [E(U) = 0]\)。则 \(h_{U} = [E(U) = 0] - \sum\limits_{\min(U) \subseteq T \subset U}^{} h_{T} \times [E(U/T) =0]\)。时间复杂度 \(O(3^n)\)。
总复杂度 \(O(3^nn + 2^nn\log V)\)。
实现细节。显然 \(f_{*,*}\) 的空间是 \(O(4^n)\) 的。但是对于 \(i\) 来说,\([1,i-1]\) 只需要存哪些是 \(s\) 中的,\([i+1,n]\) 也只需要知道哪些是 \(U\) 中的,所以可以把两个状态压在一起,空间变成 \(O(2^n)\)。
P4921 [MtOI2018] 情侣?给我烧了!
有 \(n\) 种颜色,每种颜色 \(2\) 个。将它们重新排列,求最后 \(p_{2i}=p_{2i+1}\) 的数量恰好为 \(k\) 的方案数。
定义 \(G(n)\) 表示 \(n\) 种颜色产生 \(0\) 对相邻的同色对的方案数。那么对于产生 \(k\) 对的方案数,就是 \(\binom{n}{k}\binom{n}{k}k! 2^k \times G(n-k)\)。
那么只需要求出 \(G(n)\) 就可以了。考虑每次在最开头加一对异色点,方案数为 \(n(n-1)\)。有两种情况:
- 这一对一色点另外一半也是一对。那么只需要考虑 \(n-2\) 种颜色的方案数,为 \(2(n-1)G(n-2)\)。其中 \(2(n-1)\) 表示这一对可交换,且能差在 \((n-1)\) 个空任意一个中。
- 不是一对,相当于强制它们同色(不在一起),为 \(G(n-1)\)。
则 \(G'(n) = 4n(n-1)(2(n-1)G(n-2)+G(n-1))\)。
时间复杂度 \(O(Tn)\)。
CF1874F Jellyfish and OEIS
首先,对于两个区间 \([l_1,r_1],[l_2,r_2]\),若满足 \(l_1 < l_2 \le r_1 < r_2\),且 \(p[l_1,r_1]\) 与 \(p[l_2,r_2]\) 均为排列,这 \(p[l_2,r_1]\) 也一定为排列。因为考虑一个数 \(x \in[l_2,r_1]\),若 \(pos_x \in(r_1,r_2]\),则 \(p[l_1,r_1]\) 一定不是排列(不包含 \(x\)),反之同理。则所有 \(x \in [l_2,r_1]\) 的数都满足 \(pos_x \in [l_2,r_1]\),那么 \(p[l_2,r_1]\) 是排列。
考虑维护从 \(R_i\) 表示最小的 \(r\),使得 \(p[i,R_i]\) 是排列,若不存在则 \(R_i = i-1\)。那么所有真区间 \([i,R_i]\) 不交。
尝试根据这个性质 DP。定义 \(f_{l,r}\) 表示 \(p[l,r]\) 是排列,且满足题目条件的方案数。因为真区间 \([i,R_i]\) 不交,所以可以考虑枚举有多少个不合法的真区间,记 \(g_{l,r,x}\) 为钦定 \(x\) 个真区间不合法的方案数,则 \(f_{l,r}=\sum\limits_{x=0}^{r-l+1}(-1)^xg_{l,r,x}\)。
考虑怎么维护这个 \(g_{l,r,x}\)。显然不能随便钦定,比如我们钦定了两个区间 \([l_1,r_1],[l_2,r_2]\),且 \(r_1 < l_2\),但存在 \(r_1 < l_3 <l_2 < r_3 < r_2\),且 \(p[l_3,r_3]\) 也是排列,这时应该变成 \([l_1,r_1],[l_3,l_2 - 1],[l_2,r_3],[r_3+1,r_2]\)。
但是如果 \([l_1,r_1],[l_2,r_2]\) 是不合法的,那么 \([l_1,r_1],([l_3,l_2 - 1]),[l_2,r_3],([r_3+1,r_2])\) 也是不合法的,记 \([l_1,r_1],[l_2,r_2]\) 的容斥系数为 \(x\),那么就是 \(x + x +(-x) + (-x) +x = x\)。也就是说加入 \([l_3,r_3]\) 后再拆成不交区间会抵消掉。若以直接钦定是可行的。
因为我们只在意钦定不合法区间的奇偶性,所以可以定义 \(g_{l,r,x}\) 表示区间 \([l,r]\),钦定了若干个不合法区间,且最后有 \(x\) 个点没有被区间包含的方案数乘上容斥系数的和。对于 \(g_{l,r,x}\):
- \(r\) 是没被区间包含的点。\(g_{l,r,x}\gets g_{l,r-1,x-1}\)。
- \(r\) 是被包含的点。那么新的这个钦定的区间一定满足 \(R_i=r\)。枚举 \(i\),则 \(g_{l,r,x}\gets (-1)(r-i+1)!g_{l,i-1,x} [ m_i \ge r]\)。
- 初始化 \(g_{l,l-1,0}=1\)。
那么 \(f_{l,r}=\sum\limits_{x=0}^{r-l+1}g_{l,r,x}\times x!\)。时间复杂度 \(O(n^4)\)。
但是这么做第二个样例会输出 \(39\)。好像是确实不能随便钦定导致的,上面的证明有点莫名其妙地假。
既然不能直接钦定,考虑构造映射。具体地,对于 \(p[l,r]\),我们维护 \(\{[i,R_i]| R_i \ge i\}\),根据最开始的证明,这些区间不交。那么显然一个 \(p[l,r]\) 只会对应一个集合。再细化,我们将所有 \(m_i < R_i\) 的 \([i,R_i]\) 删了,则 \(p[l,r]\) 只会对应一个不满足条件的区间集合。尝试对这个计数。
依旧把容斥系数乘进去,定义 \(f_{l,r}\) 表示 \(p[l,r]\) 是排列,且不考虑 \([l,r]\) 被 \(m_l\) 限制时合法的方案数。\(g_{l,r,x}\) 为得到区间长度和为 \(r-l+1-x\) 也就是有 \(x\) 个位置没被包含的方案数乘上容斥系数的和。则 \(f_{l,r}=\sum\limits_{x=0}^{r-l+1}g_{l,r,x}\times x!\)。对于 \(g_{l,r,x}\),有:
- \(r\) 没被包含。\(g_{l,r,x}\gets f_{l,r-1,x}\)。
- \(r\) 被包含。则 \(R_i = r\)。枚举 \(i\),有 \(g_{l,r,x} \gets (-1)g_{l,i-1,x}\times f_{i,r} [m_i \ge r]\)。其中 \(l < i \le r\)。因为 \([i,R_i]\) 是一个集合中的区间,所以一定不存在 \(i < l' \le r' < R_i\),使得 \(p[l',r']\) 是排列且 \(m_{l'}\ge r'\)。那么方案数就是 \(f_{i,r}\) 了。
- \(g_{l,l-1,0}=1\)。
- 若 \(m_l \ge r\),则 \(g_{l,r,0}\gets (-1)f_{l,r}\)。
时间复杂度 \(O(n^4)\)。
CF2048H Kevin and Strange Operation
显然最后每个位置将会是原来序列上一段区间的 \(\max\)。
记当前序列上第 \(i\) 个数是原序列 \([l_i,r_i]\) 的最大值。
考虑操作一个位置 \(p\)。有:
- 将 \(r_i\) 变成 \(r_{i+1}\),对于 \(1 \le i < p\)。
- 删掉 \([l_p,r_p]\)。
那么相当于是将 \([l_1,r_1],[l_2,r_2],\dots,[l_m,r_m]\) 变成 \([l_1,r_2],[l_2,r_3],\dots,[l_{p-1},r_p],[l_{p+1},r_{p+1}],\dots,[l_m,r_m]\)。
将 \(l,r\) 看作两个序列,那么操作 \(p\) 就会让 \(r_1\) 删掉,让 \(l_p\) 删掉。初始时 \(l_i = i,r_i = i\)。
因为 \(r\) 是删前缀的过程,\(l\) 是删子序列的过程。所以考虑判定一个序列是否合法。具体地,如果这个序列长度为 \(m\),那么可以知道 \(r_i = n - i +1\)。维护 \(l_i\) 表示从后往前尽可能少地移动 \(l\),匹配到第 \(i\) 个时 \(l\) 的值。那么 \(l_i\) 应该是 \([1, \min(l_{i+1},n-i+1)]\) 中最大的一个 \(j\),使得 \(\max\limits_{k=j}^{n-i+1}a_k = b_i\)。显然,不合法当且仅当某一个 \(i\) 时不存在这样的 \(j\) 了。
这启发我们去维护这个 \(l\)。定义状态函数 \(f_{i,j}\) 表示后面 \(i\) 个数都保留下来了,当前的 \(l\) 是 \(j\) 且合法的方案数。分类转移:
- \(b\) 序列中这一位是 \(0\)。找到 \(i\) 前面第一个 \(1\) 的位置 \(j\)。首先要满足 \(a_i =0\)。
- \(l_{i+1} > i\)。\(f_{i,i} \gets \sum\limits_{j > i}^{}f_{i+1,j}\)。
- \(j + 1 < l_{i+1} \le i\)。\(f_{i,k - 1}\gets f_{i+1,k}\)。
- \(l_{i+1} \le j+1\)。不合法。
- \(b\) 序列这一位是 \(1\)。找到 \(i\) 前面第一个 \(1\) 的位置 \(j\)。
- \(j < l_{i+1}\)。\(f_{i,j}\gets \sum\limits_{k>j}^{}f_{i+1,k}\)。
- \(l_{i+1} \le j\)。\(f_{i,k - 1}\gets f_{i+1,k}\)。
最后答案就是 \(\sum\limits_{i=1}^{n}\sum\limits_{j=1}^{i}f_{i,j}\)。直接做时间复杂度 \(O(n^2)\)。
将这两个转移合在一起,有:
- \(f_{i,k} = [a_i = 0] f_{i+1,k+1}\),对于 \(k=i\)。
- \(f_{i,k} = [a_i=0]f_{i+1,k+1}\),对于 \(j < k \le i - 1\)。
- \(f_{i,k} = \sum\limits_{x = k + 1}^{i+1}f_{i+1,x}\),对于 \(k=j\)。
- \(f_{i,k} = f_{i,k+1}\),对于 \(k < j\)。
明显是一个整体 DP 的形式。首先这个平移是整体平移的,所以可以不管。维护 \(\delta_i = n-i\) 表示平移量。
首先 \(k -\delta_i > i\) 的 \(f\) 值和 \(k - \delta = 0\) 的 \(f\) 值需要清空。也就是 \(f_{k} = 0[k > i+\delta_i\lor k = \delta]\)。
其次如果 \(a_i \ne 0\)。\(f_{k} = 0[k > j +\delta_i ]\)。
最后对于 \(k = j + \delta_i\),有 \(f_{k} = \sum\limits_{x = k}^{n}f'_x\)。
线段树维护可以做到 \(O(n\log n)\)。
CF2048G Kevin and Matrices
比 H 难,不支持反驳。
考虑判定一个矩阵是否合法。假设第 \(i\) 行的最大值不大于第 \(j\) 列的最小值。那么说明第 \(i\) 行的最大值和第 \(j\) 列的最小值都是 \(a_{i,j}\)。因为如果第 \(i\) 行的最大值不是 \(a_{i,j}\),则存在 \(a_{i,k} > a_{i,j}\),而第 \(j\) 列的最下值 \(\le a_{i,j}\),显然不合法。反之同理。
那么一个矩阵合法,当且仅当存在 \((i,j)\),使得 \(a_{i,j}\) 是第 \(i\) 行的最大值也是第 \(j\) 列的最小值。
发现如果 \((i_1,j_1)\) 合法,\((i_2,j_2)\) 也合法,且 \((i_2,j_2)\) 在 \((i_1,j_1)\) 右上角,一定满足 \(a_{i_1,j_1} = a_{i_2,j_2}\)。左上角也是一样的。也就是说,这样合法的 \((i,j)\) 的值一定都相同。同时,\((i_2,j_1)\) 和 \((i_1,j_2)\) 也是合法的。
也就是说,只要我们知道哪些行上有合法点,记为集合 \(A\);哪些列上有合法点,记为 \(B\)。那么 \((i,j),i\in A,j\in B\) 一定是合法点。
那么考虑对这玩意容斥。钦定有 \(i\) 行 \(j\) 列上存在合法点。容斥系数应该是 \((-1)^{i+j}\)。枚举这个相同的值 \(k\),那么每行都有至少 \(j\) 个数是 \(k\),且剩下的数不超过 \(k\);每列都有至少 \(i\) 个数是 \(k\),且剩下的数不小于 \(k\)。不难发现除去这 \(i \times j\) 个一定是 \(k\) 的数后,剩下每行每列的数位置都是互不相同的,于是方案数为 \((v - k +1)^{j\times n - i\times j}\times k ^{i\times m -i\times j}\times v^{(n-i)(m-j)}\)。
那么答案为:
时间复杂度 \(O(nv\log m)\)。
P14686 [ICPC 2025 Yokohama R] Charity Raffle
考虑对一种获得奖品的方案的合法性判定。
可以这么构造:
- 如果当前值剩下一种奖品 \(x\)。
- 存在 \(y > x\),且初始时 \(cnt_y = cnt_x - 1\)。合法。
- 不存在。不合法。
- 如果当前剩下大于一种奖品。将最小的那个奖品 \(x\) 和后面一个与它获得数量相同的 \(y\) 放一起,使得 \(x\) 数量加 \(1\)。之后让所有还有剩下的奖品都和 \(x\) 放一起一次,使得所有剩下的奖品数量增加 \(1\)。
发现这样的话,我们其实只需要在意出现次数最大的那个奖品 \(x\)。如果有多个一定合法。
- \(cnt_x\) 比 \(\max\limits_{y\ne x}^{} cnt_y + 1\) 大。一定不合法。
- \(x\) 后面没有次大值。一定不合法。
反之一定合法。
那么问题变成:求 \(cnt\) 的方案数,使得:
- \(\sum\limits_{i=1}^{n}cnt_i = k\)。
- \(cnt_i \le m\)。
- 如果只有 \(1\) 个最大值,最大值后面一定有一个等于它减 \(1\)。
用总的减去不合法的。
- 最大值比次大值大至少 \(2\)。枚举最大值为 \(x\)。那么问题变成 \(n-1\) 个数,\(cnt_i \le x - 2\)。答案就是 \(n \sum\limits_{i=0}^{\min(n-1,\frac{k-x}{(x-1)})}(-1)^i\binom{n-1}{i}\binom{(k-x)-i(x-1)+(n-1)-1}{n-1-1}\)。这个是调和级数的,时间复杂度 \(O(n\log n)\)。
- 最大值比次大值多 \(1\) 但最大值后面不存在次大值。强制钦定最后一个次大值是最大值,也就是给它额外加 \(1\)。那么总的方案数为 \(\sum\limits_{i=0}^{\min(n,\frac{k-1}{m})}(-1)^i\binom{n}{i}\binom{(k-1)-im+n-1}{n-1}\)。然后还需要减去只有一个次大值的情况,枚举次大值的值 \(x\)。方案数为 \(n\sum\limits_{i=0}^{\min(n-1,\frac{k-x-1}{x})}(-1)^i\binom{n-1}{i}\binom{(k-x-1)-ix+(n-1)-1}{n-1-1}\)。
记 \(G(n,k,x) = \sum\limits_{i=0}^{\min(n,\frac{k}{x+1})}(-1)^i \binom{n}{i}\binom{k-i(x+1)+n-1}{n-1}\),那么答案就是:
时间复杂度 \(O(n)\)。
P8340 [AHOI2022] 山河重整
求有多少个集合做 \(01\) 背包可以得到 \([1,n]\) 每个数。
显然每次加入一个数 \(i\) 后能得到的数应该是一个 \([1,n]\) 的前缀(从小到大加入 \(i\))。不妨设第一次由前缀分裂成区间时加入的数是 \(x\),前缀是 \([1,y]\)。那么分裂的区间变成 \([1,y]\cup [x,x + y]\)。而后由于能够加入的数都 \(>x\),所以 \([y + 1,x-1]\) 是一定得不到的,不可能合法。
考虑容斥。枚举第一个无法得到的数 \(x\)。因为我们知道一个前缀分裂成区间后就不可能恢复了,所以这个 \(x\) 一定是第一次分裂时产生的。也就是 \([1,x-1]\) 中选择的数恰好能得到 \([1,x-1]\),且后面选择了一个 \(>x\) 的数。那么 \([1,x-1]\) 中选择的数的和一定是 \(x-1\)。
定义 \(f_i\) 表示 \([1,i]\) 中选数,和恰好是 \(i\) 且能得到 \([1,i]\) 中每个数的方案数。那么答案应该是 \(g_n =2^n -\sum\limits_{x=1}^{n}2^{n-x}f_{x-1}\)。对于 \(f\),依旧考虑容斥。枚举第一个不能得到的数 \(x\),那么 \(f_{n} = w_{1,n,n} - \sum\limits_{x=1}^{n}f_{x-1}w_{x+1,n,n-x+1}\)。其中 \(w_{l,r,x}\) 为在 \([l,r]\) 中选数,和恰好是 \(x\) 的方案数。
首先对于 \(w_{1,n,n}\) 是简单的。不妨设 \(dp_{i,j}\) 为选了 \(i\) 个数,和为 \(j\) 的方案数。那么:
因为最多选 \(\sqrt{n}\) 个数,所以复杂度是 \(O(n\sqrt{n})\) 的。
对于后面一半,枚举选了 \(k\) 个数,那么它们的和至少是 \((x+1)k\)。则问题变成 \([1,n-x]\) 中选一些数,使得和为 \(n-x+1-(x+1)k\)。有 \(f_{n} = \sum dp_{i,n} -\sum\limits_{x=1}^{n}f_{x-1}\sum\limits_{k=1}^{n-x}dp_{k,n-x+1-(x+1)k}\)。考虑维护 \(h_{i,j}\) 表示现在还有 \(i\) 个数要增加,当前和为 \(j\) 的方案数。那么对于 \(x\) 来说,枚举它最后给某个 \(n\) 贡献了 \(k\) 个数,有 \(h_{k,x-1+(x+1)k}\gets f_{x-1}\)。然后对于 \(h\),有:
因为互不相同,所以每次最多弹一个数出去。
最后有 \(f_{n} = \sum dp_{i,n} - h_{0,n}\)。然后这玩意要半在线地做,而 \(f_{x-1}\) 不会对 \(n< 2x\) 的点产生贡献,所以每次折半就行了。具体地,先处理 \([1,\frac{n}{2}]\) 再处理 \([1,\frac{n}{2}]\) 对 \([\frac{n}{2}+1,n]\) 的贡献。时间复杂度 \(T(n) = O(n\sqrt{n} )+ T(\frac{n}{2}) = O(n\sqrt{n})\)。
P8434 「WHOI-2」D&D
首先 \(\max(A)\) 一定在装饰子集里面。那是不是就可以根据这个性质来计数。
因为要让最后装饰子集相同,所以首先所有区间都包含 \(\max(A)\)。此时所有 \(x | \max(A) = \max(A)\) 的点都不重要,删去之后最大的那个值也一定在装饰子集里面。然后继续这么做。
这样我们就可以得到装饰子集里有哪些数了。问题就变成划分区间,使得每个区间都包含这些数的方案数。
考虑先求出整个序列 \(A\) 的装饰子集。发现其实根本不需要这么麻烦,因为值域只有 \(2\times 10^6\),所以高维后缀和维护一下是否存在 \(x\) 的超集就行了。
然后对于每个 \(i\),维护 \(l_i\) 表示如果 \(i\) 是一个区间的右端点,左端点的最大值,使得 \([l_i,i]\) 包含 \(A\) 的装饰子集中所有点。这个滑动窗口一下就行了,开个桶。
那么定义 \(f_i\) 表示 \(i\) 是右端点的时候的方案数,有 \(f_{i }= \sum f_j [j < l_i]\)。前缀和优化即可。时间复杂度 \(O(n+V\log V)\)。
然后你会发现暴力能过。
QOJ2626 Kilk Not
给定 \(0,1,?\) 序列,将 \(?\) 中的 \(a\) 个变成 \(0\),剩下的变成 \(1\),使得最长的相同子段长度最小。
考虑二分答案,记上界为 \(k\)。记 \(S_1\) 为所有不超过上界的合法字符串中,\(0\) 数量最小的;\(S_2\) 为最大的。那么当 \(\sum [S_{1,i} = 0] \le \sum[s_i =0] + a \le \sum [S_{2,i}=0]\) 时一定存在构造,使得 \(0\) 的数量为 \(\sum [s_i =0] +a\) 且不超过上界。
考虑证明这个东西。记 \(T_i = S_{1}[1\dots i] + S_2[i+1\dots n]\)。因为 \(i \to i+1\) 时:
- 若 \(S_{2,i+1} = 0\)。此时 \(c(T_{i+1}) \in \{c(T_{i})-1,c(T_i)\}\)。
- 若 \(S_{2,i+1}=1\)。此时 \(c(T_{i+1})\in \{c(T_{i}),c(T_{i})+1\}\)。
那么根据界值定理,显然存在某个时刻 \(T_i\) 中 \(0\) 的数量为 \(\sum [s_i=0]+a\)。
同时,因为 \(S_{1},S_2\) 任意一个子串都不超过上界,所以某个 \(S_{1,i-1}\ne S_{2,i} \land c(T_i) = \sum [s_i=0]+a\) 也不超过上界。又因为在 \(c(T)\) 变化的时候,一定存在某个时刻使得 \(c(T_i) =\sum [s_i=0]+a\) 且 \(c(T_i) \ne c(T_{i-1})\),所以构造也是一定存在的。
则问题变成找到 \(0\) 最小的不超过上界的合法字符串和 \(0\) 最大的。拿最小的举例,定义 \(f_{i,0/1}\) 表示 \(s[1\dots i]\) 填完,\(s_i = 0/1\) 且不超过上界时 \(0\) 数量的最小值。那么:
- \(s_{i} \ne 0\)。\(f_{i,1} = \min\limits_{j=\max(0,i-k)}^{i-1}(f_{j,0})\)。额外条件是 \([j+1,i]\) 不存在 \(s_i = 0\)。
- \(s_i \ne 1\)。\(f_{i,0} = \min\limits_{j=\max(0,i-k)}^{i-1}(f_{j,1}+i-j)\)。额外条件是 \([j+1,i]\) 不存在 \(s_i = 1\)。
单调队列一下就行了,时间复杂度 \(O(n)\)。
最后构造只需要维护个方案,然后找到那样一个 \(i\) 拼起来就行了。总时间复杂度 \(O(n\log n)\)。
P10813 【MX-S2-T4】 换
先考虑只有 \(0,1\) 怎么做。
直接去状压,维护 \(f_{i,s}\) 表示进行到第 \(i\) 步,当前序列状态为 \(s\) 的方案数。时间复杂度 \(O(m2^n)\)。
假设我们已经知道这个序列 \(a\) 了,发现判定条件等价于将 \(a\) 离散化后对于 \(i = 1\dots len\)(\(len\) 是 \(a_i\) 的种类数),将 \(a_j < i\) 的看成 \(0\),\(a_j \ge i\) 的看成 \(1\) 后得到的 \(0,1\) 序列合法。
记 \(g_{s}\) 表示当 \(0,1\) 序列状态为 \(s\) 时的合法性。这个倒着状压就行了。
观察 \(i\) 从 \(1\) 到 \(len\) 的 \(0,1\) 序列的变化,记 \(s_i=\{j|a_j < i\}\)。有 \(s_1 = \emptyset\),\(s_{i-1}\subsetneq s_{i}\),且 \(s_{len} = \{1,2,\dots,n\}\)。
那这题就可以做了。定义 \(dp_{i,S}\) 表示 \(s_{i}=S\) 时的方案数。则 \(dp_{i,S} = \sum\limits_{T\subsetneq S}^{} dp_{i-1,T} [g_{U \oplus T}=1]\)。只需要做 \(n\) 次高维前缀和,时间复杂度 \(O(n^22^n)\)。
对于答案。如果 \(a_i\) 的种类数为 \(k\),在 \(1 \le a_i \le V\) 的条件下方案数为 \(\binom{V}{k}\)。那么答案就是 \(\sum\limits_{i=1}^{n}dp_{i,U} \times \binom{V}{i}\)。总时间复杂度 \(O(m2^n+n^22^n)\)。
P6838 [IOI 2020] 网络站点
题目是说,要实现两个函数。第一个函数会被调用不超过 \(9\) 次,每次会给一棵树,需要给这棵树重标号且编号互不相同、最大值不超过 \(1000\)。第二个函数会被调用若干次,每次会给定某棵之前树上两个点 \(s,t\) 和 \(s\) 的相邻点编号,要求如果要从 \(s\) 到 \(t\) 走简单路径,下一步应该走哪个点。这里编号都是第一个函数重标号后的值。
也就是说,我需要通过给树重新编号的方式快速判断这棵树长啥样。
直观感受是想构造一个类似于 DFS 序的东西,因为 DFS 序上通过相邻两个儿子 \(u,v\) 就可以知道 \(u\) 子树内点的 DFS 序编号在 \([dfn_u,dfn_v)\)。但是不难发现最后一个儿子子树编号区间是无法表示的,因为我并不知道这个点的 \(siz\)。
想到定义另一种 DFS 序,这种 DFS 序先对子树标号,再给当前子树的根标号。可以叫逆 DFS 序(?)发现这么干的缺点在于我们不知道第一个儿子子树编号区间。
不难想到把这俩拼起来。具体地,我们对树按照深度黑白染色。对于黑点,先给它自己编号再给子树编号;对于白点,先给子树编号再给它自己编号。
那么对于一个查询 \((s,t,c)\)。首先可以通过 \(c\) 中编号最大值和 \(s\) 的大小关系得知 \(s\) 是黑点还是白点。
- \(s\) 是黑点。\(s\) 父亲的编号应该是 \(c\) 中编号最大值。\(s\) 第一个儿子子树范围应该是 \((s,c_0]\)。因为 \(s\) 的儿子是白点(编号在子树内是最大的)。同理 \(s\) 第二个儿子范围是 \((c_0,c_1]\)。\(s\) 最后一个儿子范围是 \((c_{k-1},c_k]\),其中 \(c_k\) 是 \(c\) 中次大值。那么剩下的点都应该在子树外了。举个例子,如果 \(s=5,c = \{9,10,11\}\)。那么 \(s\) 的各个儿子子树编号范围应该是:\((5,9],(9,10]\)。
- \(s\) 是白点。\(s\) 父亲的编号应该是 \(c\) 中编号最小值。\(s\) 第 \(i\) 个儿子范围是 \([c_{i},c_{i+1})\)。最后一个儿子的范围是 \([c_{k},s)\)。剩下的都在子树外。举个例子,如果 \(s = 11,c =\{1,2,5\}\)。那么 \(s\) 的各个儿子子树编号范围应该是:\([2,5),[5,11)\)。
时间复杂度 \(O(\sum n)\)。
P10440 [JOIST 2024] 环岛旅行 / Island Hopping
首先查询每个点和 \(1\) 的距离,花费 \(n-1\) 次查询。
对于每个点 \(u\),如果 \(u \ne 1\) 那么 \(u\) 的父亲 \(fa_u\) 一定满足 \(dis(fa_u,1)<dis(u,1)\)。则我们一直查询 \(u\),直到满足 \(dis(x,1)<dis(u,1)\)。由此可以得到 \(fa_u = x\)。注意到查询过程中如果 \(dis(x,1)> dis(u,1)\),那么 \(fa_x\) 一定是 \(u\)。所以只需要 \(n-1\) 次查询。
一共 \(2n-2\) 次查询。时间复杂度 \(O(n)\)。
AT_kupc2020_m Many Parentheses
先不考虑 \(k\) 的限制。
可以在每组划分位置上来一个 \((\),例如:\((())()()((()))\) 如果划分成 \([(())][()()][((()))]\),就可以变成字符串 \(((())(()()(((()))\)。
记 \(c_i\) 为前缀 \((\) 的数量减去 \()\) 的数量。显然第 \(i\) 个盒子的结尾应该是最后一个满足 \(c_j = i\) 的位置。且这个位置一定存在。这里是最后一个的原因是每个盒子往后不可能存在 \()\) 数量比 \((\) 大的情况。
那么只需要看 \(m+n\) 个 \((\) 和 \(m\) 个 \()\) 组成的,满足 \(c_i \ge 1\) 的字符串数量。记这个方案数为 \(f(n,m)\)。
对于 \(k\) 的限制。枚举有 \(x\) 个长度为 \(2k\),那么方案数为 \(f(1,k)^x f(n - x, m - xk)\binom{n}{x}\),容斥系数显然 \((-1)^{x}\)。
答案为 \(\sum\limits_{x=0}^{n}(-1)^x f(1,k)^x f(n - x, m - xk)\binom{n}{x}\)。
对于 \(f(n,m)\),相当于可以向上、右走(从 \((0,1)\) 开始),走到 \((m,n+m)\) 且不触碰 \(y = x\) 的方案数。有 \(f(n,m) = \binom{(n+m-1)+(m)}{n+m-1} - \binom{(m-1)+ (n + m)}{m - 1}\)。
时间复杂度 \(O(n)\)。
CF1019C Sergey's problem
如果原图是 DAG。那么按照拓扑排序跑一遍就行了,且非集合中的点一定能由集合中某个点走 \(1\) 步到达。因为如果需要两步说明 \(u\) 的所有入点都不在集合内,此应该把 \(u\) 加入集合。
考虑原图是一般有向图。那么就需要通过这额外的 \(1\) 步到达所有点。
只要能找到一个导出子图是 DAG,且不在导出子图中的点都存在一个入边在这个导出子图就行了。
考虑维护这个导出子图。对于点 \(u\):
- 当前导出子图中存在至少一个点指向 \(u\)。不加入导出子图。
- 当前导出子图中不存在一个点指向 \(u\)。那么将 \(u\) 加入后也是 DAG,因为 \(u\) 是 \(0\) 入度点。
再对这个导出子图跑拓扑就行了。
时间复杂度 \(O(n)\)。

浙公网安备 33010602011771号