Atcoder-Countings1
- Atcoder-Countings1
- Intro
- AC1 ARC144D AND OR Equation(2468)
- AC2 ABC273G Row Column Sums 2(2521)
- AC3 AGC012D Colorful Balls(2760)
- AC4 AGC040C Neither AB nor BA(2740)
- AC5 ABC267G Increasing K Times(2561)
- AC6 AGC049D Convex Sequence(2602)
- AC7 AGC046C Shift(2130)
- AC8 ARC071F Infinite Sequence(2336)
- AC9 ARC110D Binomial Coefficient is Fun(2078)
- AC10 ARC110E Shorten ABC(2973)
- AC11 ARC111F Do you like query problems(3119)
- AC12 ARC128D Neq Neq(2554)
- AC13 ARC115D Odd Degree(2325)
- ARC115E LEQ and NEQ(2363)
- AC15 AGC036C GP 2(2357)
- AC16 ARC028D 注文の多い高橋商店(2997)
- AC17 Span Covering(3012)
- ARC154E Reverse and Inversion(3506)
- AC19 ARC153F Tri-Colored Paths(3597)
- ARC155F Directable as Desired
- AC21 ABC222H Beautiful Binary Tree(3477)
- ABC134F Permutation Oddness(2532)
- Three Gluttons(3315)
- AC24 ARC108D AB(1987)
- AC25 ARC108F Paint Tree(2646)
Atcoder-Countings1
Intro
丰富多彩的计数题是 Atcoder 的一大特色,此系列专门收录 Atcoder 上的计数题。
(个人:有些题解比较长的,新建一个文档,但一般还是放在这篇文章中,方便查看)
对我影响最大的是 zhzx 的 ckr 巨佬的计数讲课 和 Appleblue17 的计数题单。
个人习惯,\(x \leftarrow y\) 均表示 \(x+=y\)。
AC1 ARC144D AND OR Equation(2468)
开国元勋。意义重大,故另起一篇。
AC2 ABC273G Row Column Sums 2(2521)
Atcoder:ABC273G Row Column Sums 2
Problem
给定正整数\(N\),求有多少个 \(N\times N\) 的矩阵满足以下条件:
- 对于所有 \(1\leq i\leq N\),第 i 行上所有数之和为 \(R_i\) 。
- 对于所有 \(1\leq i\leq N\),第 i 列上所有数之和为 \(C_i\) 。
\(C_i\) , \(R_i\) 都是 \(0\) 到 \(2\) 之间的正整数。
答案对 \(998244353\) 取模。
- \(1\ \leq\ N\ \leq\ 5000\)
- \(0\ \leq\ R_i\ \leq\ 2\)
- \(0\ \leq\ C_i\ \leq\ 2\)
Solution
显然 \(\sum{r} = \sum{c}\),否则答案为 \(0\)。
这个 dp 反正我是想不出来。
记 \(f[i][x]\) 为填了前 \(i\) 行,剩下的位置中有 \(x\) 列要求和为 \(2\)。
那么记初始有 \(x_0\) 列和为 \(2\),则 \(f[0][x_0] = 1\),答案为 \(f[n][0]\)。
转移反而好想。
首先要预知两个值:剩下的列中,和为 \(1\) 的列数和和为 \(2\) 的列数。分别记为 \(y\) 和 \(x\)。
若 \(r_i = 0\):\(f[i][x] = f[i - 1][x]\)。就是啥也不干。
若 \(r_i = 1\):\(f[i][x] = f[i - 1][x](y + 1) + f[i - 1][x + 1](x + 1)\)。
若 \(r_i = 2\):\(f[i][x] = f[i - 1][x + 1](x + 1) + f[i - 1][x + 2]\binom{x + 2}{2} + f[i - 1][x]\binom{y + 2}{y} + f[i - 1][x + 1](x + 1)y\)。
AC3 AGC012D Colorful Balls(2760)
Atcoder:AGC012D Colorful Balls
Problem
\(N\) 个球排成一排,第 \(i\) 个球的颜色为 \(c_i\),重量为 \(w_i\)。我们定义「一次操作」为:选择两个颜色相同,且重量之和不超过 \(X\) 的球,交换它们的位置;或选择两个颜色不同,且重量之和不超过 \(Y\) 的球,交换它们的位置。问进行任意次操作后,可以得到多少种不同的颜色序列。输出答案对 \(10^9+7\) 取模的结果。
- \(1\ ≦\ N\ ≦\ 2\ ×\ 10^5\)
- \(1\ ≦\ X,\ Y\ ≦\ 10^9\)
- \(1\ ≦\ c_i\ ≦\ N\)
- \(1\ ≦\ w_i\ ≦\ 10^9\)
Solution
推性质:传递性:如果 \(a\) 和 \(b\) 可以交换,\(a\) 与 \(c\) 可以交换,则 \(b\) 与 \(c\) 可以交换。讨论一下就可以了,自证不难。
由此易得 \(O(n^2)\) 做法,枚举一下每两个点是否连通,然后对于每个连通块单独计算方案数再乘起来。
单个连通块的方案数为 \(\frac{(\sum{s_i})!}{\prod(s_i!)}\),这个不难。
优化,考虑少一些判定,也就是用最少的边还原出本来的连通块状态而不考虑每个连通块内的连边情况。
官方题解的思考方式我觉得更自然全面,即将任意一条两个点直接或间接可达的路径转化成数量级为 \(O(n)\) 的特殊边。
-
考虑同色两点 \(u\) 和 \(v\),记该色最小重量点为 \(x\),则 \(u - v \iff u - x - v\)。
-
考虑异色两点 \(u\) 和 \(v\),记最小重量最小的颜色为 \(a\),最小重量次小的颜色为 \(b\),分别对应该色最小重量点为 \(x, y\)。
- \(col_u \ne a,col_v\ne a\):\(u - v \iff u - y - v\)。
- \(col_u \ne b,col_v\ne b\):\(u - v \iff u - x - v\)。
- \(col_u = a,col_v = b\):\(u - v \iff u - y - x - v\)。
构造满足每条边的两端点重量之和 \(\le w_u + w_v\)。
然后 \(x - y\) 连边显然合法(针对第一条),所以如果任意异色两点连通,它们必定与 \(x\) 连通。
而对于不与 \(x\) 连通的点 \(w\),\(w\) 所在连通块不可能存在异色,由单个连通块贡献的计算式,这些块方案唯一,不会产生贡献。
总结一下,我们只需计算 \(x\) 所在连通块价值。
连边方式,同色连向该色最小重量点,各色最小重量点连向全局最小重量点,全局最小重量点的颜色对应的所有点连向最小重量次小颜色的最小重量点。这样是 \(O(n)\) 的。
AC4 AGC040C Neither AB nor BA(2740)
Atcoder:AGC040C Neither AB nor BA
Problem
给出一个大于0的偶数 \(N\) 。
请找出长度为 \(N\) ,由'A
','B
','C
'这三个字母组成且可以由下列规则把其变为空串的字符串 \(s\) 的数量。
- 不断选择\(s\)中任意除'
AB
'和'BA
'外的长度为2的子串并删除。
比如'ABBC
'是\(N=4\)条件下的一个合法字符串,因为我们可以通过这样的方式将其变为空串:
'ABBC
'→(删除'BB
')→'AC
'→(删除'AC
')→'(空串)
'
答案可能很大,所以请将结果对\(998244353\)取模。
- \(2 \le N \le 10^7\)
- \(N\) 是偶数
Solution
妙妙的等价转化。AB
和 BA
不太好考虑,我们希望能够有一个容易判断是否能合法删除的序列。
由于成对删除,黑白染色 是一种常见的成对考虑的套路。
对序列黑白染色,并且将黑色位置的 A
变成 B
,B
变成 A
。转化前后的序列是 一一对应 的,这是一种很舒服的体验。
这样我们发现只有 AA
和 BB
不能删除,易知合法序列为 \(A\) 的数量和 \(B\) 的数量都不超过 \(\frac{n}{2}\) 的序列。
直接做不好想,考虑容斥。总序列数 \(3^{n}\),枚举 \(A\) 的数量为 \(\frac{n}{2} + 1,\frac{n}{2} + 2,...\),减去这部分的序列数。
由于 \(A\) 和 \(B\) 的数量最多只有一个不合法,因此不会算重,减去时直接乘上一个系数 \(2\) 。
即 \(Ans = 3^{n} - 2\sum\limits_{i = \frac{n}{2} + 1}^{n}2^{n - i}\binom{n}{i}\)。
AC5 ABC267G Increasing K Times(2561)
Atcoder:ABC267G Increasing K Times
Problem
给定一个正整数序列 \(A=(a_1,a_2,\ldots,a_n)\),问有多少个 \(1\sim n\) 的排列 \(P=(p_1,p_2,\ldots,p_n)\) 满足:
- 存在恰好 \(k\) 个整数 \(i(1\leqslant i\leqslant n-1)\) 满足 \(a_{p_i}<a_{p_{i+1}}\)
对 \(998244353\) 取模。
\(2\leqslant n\leqslant 5000,0\leqslant k\leqslant n-1,1\leqslant a_i\leqslant n\)
Solution
还是等价的思想,将原序列排序后计数,答案是一样的。
然后是一个比较简单的 dp。记 \(f_{i, j}\) 表示考虑前 \(i\) 个数,产生 \(j\) 上升的方案数。
考虑不产生上升:
- 插在序列前面:\(1\) 种方案。
- 插在一个上升的中间:\(j\) 种方案。
- 插在相同的数的后面:若之前又 \(x\) 个相同的数,则有 \(x\) 种方案。
考虑从小到大插入数,上升的数量单调不减,因此剩下的情况就会产生至多 \(1\) 个上升,共 \(i + 1 - (j + 1 + x) = i - j - x\) 种方案。
边界为 \(f_{1, 0} = 1\)。甚至还可以滚动数组。
AC6 AGC049D Convex Sequence(2602)
Atcoder:AGC049D Convex Sequence
Problem
给定整数 \(N\) 和 \(M\),问有多少个长为 \(N\) 的非负整数数列 \(A\),满足以下条件:
- \(A_1+A_2+\ldots+A_N = M\)
- 对任意 \(i(2 \leq i \leq N-1)\) ,都有 \(2A_i \leq A_{i-1} + A_{i+1}\)
答案对 \(10^9+7\) 取模。
- \(1\ \leq\ N\ \leq\ 10^5\)
- \(1\ \leq\ M\ \leq\ 10^5\)
Solution
\(2a_i \le a_{i - 1} + a_{i + 1} \iff a_{i} - a_{i + 1} \le a_{i - 1}- a_{i}\)。
可以用 差分 来理解式子,也可以把这个序列看成是 凸性 的,具体这道题是下凸。
考虑如何构造一个合法序列。
枚举第一个最小值的位置 \(i\)。
- 整个数列加 \(1\)。
- 选择 \(j < i\),给 \(a_j, a_{j - 1},a_{j - 2},\cdots, a_1\) 分别加上 \(1, 2, 3,\cdots\)。由于我们限制 \(i\) 必须是第一个最小值,因此必须选择 \(j = i - 1\) 进行一次这种操作。
- 选择 \(j > i\),给 \(a_j, a_{j + 1}, a_{j + 2},\cdots, a_n\) 分别加上 \(1, 2, 3,\cdots\)。
不同的 \(i\) 对应的数列一定不同,相同 \(i\) 的不同高度对应的数列一定不同。对于一个第一个最小值的位置为 \(i\) 的数列,其操作序列是固定的,即 操作序列与数列是一一对应的。
这一点很重要,因为这样我们就可以仅仅从操作序列求得答案。
考虑操作的过程相当于一个完全背包问题,从前往后枚举 \(i\) 的过程中,要对背包进行增加和删除物品的操作。
考虑有效的背包物品数量为 \(O(\sqrt{m})\),因此时间复杂度没有问题。
这个可以当 可修改完全背包板子。
AC7 AGC046C Shift(2130)
Problem
给定一个只由 0
和 1
组成的序列 \(S\) 。求对 \(S\) 进行以下的操作 \([0,k]\) 次后可以得到的字符串种类个数模 \(998244353\) 后的值。
-
将一个
1
移到它左边的任意一个0
的左边。 -
\(1 \le |S| \le 300\)
-
\(0 \le k \le 10^9\)
-
\(S\) 只包含
0
和1
Solution
记共有 \(m\) 个 \(0\),\(a_i\) 表示第 \(i - 1\) 个 \(0\) 到第 \(i\) 个 \(0\) 之间的 \(1\) 的数量。
转化操作意义,相当于每次选择 \(i < j\),令 \(a_i\) 加一,\(a_j\) 减一。
我们发现,仅凭 \(a_i\) 就足以定出原字符串!因此这波转化很妙,既简化了操作,又方便计数。
答案即为至多操作 \(K\) 可以得到的 \(\{a_i \}\) 的数量。
不考虑操作次数,通过 \(\{ a_i \}\) 得到 \(\{b_i \}\) 的充要条件为:
- \(\sum\limits_{i = 1}^{m}a_i = \sum\limits_{i = 1}^{m}b_i\)。
- \(\forall i \in [1, m], \sum\limits_{j = 1}^{i}b_j \ge \sum\limits_{j = 1}^{i}a_{j}\)。
第一个条件是恒成立的,因此重点在第二个条件。
考虑操作次数,则需要知道通过 \(\{ a_i \}\) 得到 \(\{b_i \}\) 的最小操作次数,这个最小值为 \(\sum\limits_{i = 1}^{m}\max(b_i - a_i, 0)\)。不难理解,就是把某些块内多出来的 \(1\) 分配给少 \(1\) 的块内。同时我们知道,当 \(K \ge 300\) 时,则答案等同于 \(K = 300\)。
还有一个细节就是,在 \(S\) 末尾添加一个 0
,把最后一段 1
给统计进去。显然,末尾的 0
并不会影响答案。
设计 dp 状态,记 \(f[i][j][k]\) 表示 \(\sum\limits_{x = 1}^{i}b_{x} = j\),\(\sum\limits_{x = 1}^{i}\max(b_x - a_x, 0) = k\) 的方案数。
转移方程为:
由于每一层循环都有一定的范围,因此实际上几乎跑不满,\(O(n^4)\) 可以艹过去。
AC8 ARC071F Infinite Sequence(2336)
Atcoder:ARC071F Infinite Sequence
Problem
定义 \(n-\)可爱序列 指无限长的由 \(\{1,2...,n\}\) 组成的序列。同时 \(a_1,a_2...\)满足以下条件:
1.第 \(n\) 个及以后的元素是相同的,即若 \(\forall i,j\geq n,a_i=a_j\) 。
2.对于每个位置 \(i\),紧随第 \(i\) 个元素后的 \(a_i\) 个元素是相同的,即若 \(\forall i<j<k≤i+a_i,a_j=a_k\)。
输入 \(n\),请输出 \(n-\)可爱序列的数量 \(\bmod 10^9+7\) 。
\(n\leq{10^6}\)。
Solution
模拟一下,容易发现一个结论,当 \(a_i > 1\) 且 \(a_{i + 1} > 1\) 时,后面的序列都会固定下来,即 \(a_i a_{i + 1}a_{i + 1}a_{i + 1}\cdots\)
直觉上反向 dp 会好想一些,设 \(f_i\) 表示填完第 \(i\sim n\) 位合法的方案数。分类讨论:
- \(a_i = 1\):后面放什么都无所谓,\(f_{i} \leftarrow f_{i + 1}\)。
- \(a_i > 1\):
- \(a_{i + 1} > 1\):方案只由 \(a_i\) 与 \(a_{i + 1}\) 的取值决定,\(f_{i} \leftarrow (n - 1)^{2}\)。
- \(a_{i + 1} = 1\):根据题意,位置 \(i\) 后为一段固定的长度为 \(i\) 的 \(1\) 序列,而之后的序列没有关于 \(a_{i}\) 和 \(a_{i + 1}\) 的限制,可以任意合法放置,因此 \(f_{i} \leftarrow f_{i + a_{i} + 1}\)。这里枚举 \(a_i\) 是 \(O(n)\) 的,但发现其取值连续,可以通过维护一个前缀和(后缀和?)\(O(1)\) 转移。
\(f\) 的边界/越界情况要注意一下。
AC9 ARC110D Binomial Coefficient is Fun(2078)
洛谷:ARC110D Binomial Coefficient is Fun
Atcoder:ARC110D Binomial Coefficient is Fun
Problem
我们有一个包含 \(N\) 个非负整数的序列 \(A\)。
对于所有长度为 \(N\) 且和不超过 \(M\) 的非负整数序列 \(B\),求 \(\prod_{i = 1}^N {B_i \choose A_i}\) 之和, 对 \((10^9 + 7)\) 取模。
- \(1 \le N \le 2000\)
- \(1 \le M \le 10^9\)
- \(0 \le A_i \le 2000\)
Solution 1
越来越菜了,2000 级别的计数想着很困难。
令 \(S = \sum\limits_{i = 1}^{n}a_i\)。
粗略地看成是从 \(m\) 个球中选出 \(S\) 个球,但是没有考虑 \(m\) 个球的分割情况以及 \(S\) 个球的分割情况。
考虑把分界线给加进去,要分成 \(n\) 段的话,相当于要放 \(n - 1\) 个分界线。
每一段选一些数作为 \(a\),而每一段的总数就是 \(b\)。发现 \(b_i\) 的放置与顺序无关,我们可以钦定 \(b_i\) 按下标从左往右安排,由于对应的 \(a_i\) 是确定的,因此如果确定了 \(m + n - 1\) 内要选位置(\(S + n - 1\) 个位置),分界线的位置是确定的。
现在回过去看题目本身,已经对这个连乘积很模糊了,因为我们已经把 \(b\) 和 \(a\) 的分割放在了一起考虑。
但实际上我们在这个大的序列中组合时,对每一小段内,都对不同的 \(b_i\) 做了组合。
然而这么做是假定了 \(\sum\limits_{i = 1}^{n}b_i = m\)。但实际上 \(\sum\limits_{i = 1}^{n}b_i \le m\),因此有一步妙妙的方法,在 \(m + n\) 个位置中选 \(S + n\) 个位置,相当于用 \(n\) 个分界线,其中最后一个分界线在所有所选位置的末尾,专门限制 \(\sum\limits_{i = 1}^{n}b_i\) 的大小。
\(Ans = \binom{m + n}{S + n}\)。
Solution 2
普通生成函数。
AC10 ARC110E Shorten ABC(2973)
Problem
给定一个长度为 \(N\) 的字符串 \(S\),包含 A,B,C
。
你可以进行若干次如下操作:
- 选定 \(i\in [1,n-1]\),满足 \(S_i\neq S_{i+1}\),将这两个字符替换为
A,B,C
没有出现的那个,比如你可以将AB
替换为C
。
求操作后不同串的个数对 \(1000000007\) 取模。
- \(1 \leq N \leq 10^6\)
Solution
[ARC094F] Normalization 与这个题几乎一模一样。那天上午在zh机房用着自己的笔记本电脑做出了这道题,记忆犹新。
那道题将 A,B,C
替换为 0,1,2
,用了和 \(\% 3\) 相等的性质,
而这道题把 A,B,C
替换为 1,2,3
,一次操作相当于把 \(x\) 和 \(y\) 整体替换为 \(x \oplus y\),最终得到的序列就是把原序列划分成很多段,然后求每个段的异或和。
对于操作中需满足 \(x\neq y\),有以下情况是满足条件的区间:
- 区间内只有一个数。
- 区间内的异或和不为 \(0\) 且不能全为同一个数。
然而对每个段求出异或和后,不同的划分可能得到相同的结果。
我们考虑一个初始字符串 \(S\) 形成最终字符串 \(T\) 的过程:\(T\) 的每一个字符对应 \(S\) 的一段区间。
设 \(f_i\) 为考虑 \(S\) 的前 \(i\) 个字符的答案,dp
过程为在前 \(i\) 个字符形成的最终字符串后新增一个字符,而这个字符要在 \(S\) 中对应一段区间。对于多个异或和相等的区间,我们只选择长度最小的那个,这样就避免计重。
转移是这样的:(记 \(len_{i, j}\) 为以 \(i\) 为开头,形成 \(T\) 中字符 \(j\) 的 \(S\) 中的最短区间长度,\(a_i\) 为 \(S\) 中字符转化后的数字)
注意无法导出字符时,该状态无法往后转移给任意一个有用 \(f\) 值,可以把 \(nxt\) 设成 \(n + 1\)。
对于 \(f\) 的转移:
初始 \(f_0 = 1\),表示什么字符都没有算一种方案。
考虑最后如何统计答案。如果只考虑 \(f_{n}\),那么有的 \(f_{i}\) 因为我们的限制而转移不过去,但实际上可以将后面那段没法单独形成字符的区间归到已形成的串中的最后一个字符。
因此枚举每一个位置,如果 \(f_i \oplus f_n = 0\),就计入答案。可见 \(f_n\) 其实是正确答案的一部分。
AC11 ARC111F Do you like query problems(3119)
洛谷:ARC111F Do you like query problems
Atcoder:ARC111F Do you like query problems
Problem
给出三个数 \(n,m,q\)。
你有一个长度为 \(n\) 的序列 \(a\),初始全为为 \(0\),你有三种操作:
操作 \(1\):给出 \(l,r,v\),让区间 \([l,r]\) 对 \(v\) 取 \(\min\)。
操作 \(2\):给出 \(l,r,v\),让区间 \([l,r]\) 对 \(v\) 取 \(\max\)。
操作 \(3\),给出 \(l,r\),求区间和,将其累加进一个叫 \(sum\) 的变量里。
你并不需要维护这个数据结构,而是统计一共有 \(q\) 个操作的情况下,所有不同的操作序列中 \(3\) 操作得到的 \(sum\) 的总和,对 \(998244353\) 取模。你需要保证 \(v\in[0,m-1]\)。
- \(1 \leq N,M,Q \leq 200000\)
Solution 1
对所有可能的情况求某个值的和,可以考虑用期望解决问题。 类似的套路还出现在 AGC028B Removing Blocks。
(然后就是看 Appleblue17 的题解了QWQ)
而 期望可以转为概率。对值域将期望转成概率。
枚举 \(w \in [0, m)\),将 \(\ge w\) 的数标记为 \(0\),\(<w\) 的数标记为 \(1\),累计权值。
记第 \(t\) 次操作后第 \(i\) 个数为 \(1\) 的概率为 \(f_{w, t, i}\)。
操作中只有一部分会对 \(a_i\) 的值产生影响,我们(Appleblue17)记这些操作为关键操作。有两种情况:
- 区间最小值操作,\(i \in [l ,r]\),\(v < w\)。
- 区间最大值操作,\(i\in [l, r]\),\(v \ge w\)。
有一个显然的事情是,\(a_i\) 的值仅由最后一个关键操作决定。
事实上,我们可以算出 \(i, w\) 确定的情况下,一次操作是关键操作的概率。记其为 \(p_i\)。考虑包含 \(i\) 的区间概率,一次操作是修改操作的概率,对取最小/大值操作分别考虑是关键操作的概率。
若前 \(t\) 次操作没有一个是关键操作,则 \(a_i = 0\);否则,\(v\) 有 \(\frac{m - w - 1}{m}\) 的概率 \(\ge w\),从而使 \(a_i \ge w\)。即:
把枚举 \(w\in [0, m)\) 的概率在 \(t, i\) 确定时累加起来,相当于第 \(t\) 次操作后 \(a_i\) 值的期望,记为 \(g_{t, i}\):
考虑统计答案。考虑当前操作为查询的概率,枚举 \(1\sim n\) 的每一个位置,用与上面类似的方法计算合法区间的概率(也即该点被查询到的概率),然后再乘上该点的当前期望值。
需要注意的是,若枚举查询出现的时间 \(t\),实际上之前所有的值都是 \(t - 1\) 这个时间节点的,因为 \(f_{w,t, i}, g_{t, i}\) 考虑了时间 \(t\) 为修改操作的情况,这让 \(a\) 的期望值有所变化。那么把整体计算式写出来,即:(注意这里直接就枚举查询时间减一了)
还要注意,这里只是算了期望的 \(sum\) 值,但每一次操作都有 \(2m + 1\) 种,每一次操作的区间又有 \(\frac{n(n + 1)}{2}\) 种,即:
算算就可以了。
Solution 2
AC12 ARC128D Neq Neq(2554)
Problem
给定长度为 \(n\) 的序列 \(a\),可以做若干次操作:
- 选择三个连续的下标 \(x,y,z\),若 \(a_x \ne a_y,a_y \ne a_z\),则删去 \(a_y\)。
问最多能形成多少种可能的序列。
\(n \le 2 \times 10^5\),\(a_i \le n\)。
Solution
AC13 ARC115D Odd Degree(2325)
Problem
给定一个 \(n\) 个点,\(m\) 条边的无向图,求它的奇数度数点数为 \(k\) 的生成子图的个数,\(k\in [0, n]\)。
\(1\le n, m \le 5000\)。
Solution
\(k\) 为奇数时答案为 \(0\),因为一条边同时对两个点的度数奇偶性做出改变,度数为奇数的点数变化量只为 \(0\) 或 \(\pm 2\)。
先分析树再推广到图。
一般的做法是,用 \(dp_{i,j, 0/1}\) 表示 \(i\) 子树内有 \(j\) 个点的度数为奇数,其中 \(0/1\) 表示点 \(i\) 的度数奇偶性,然后跑树上背包。
另一种做法则挖掘出了组合结论:强行钦定 \(k\) 个点为度数为奇数的点,发现一定有唯一满足的生成子图,所以对一个偶数 \(k\),对应的方案数为 \(\binom{|V|}{k}\)。
现在再来看图上问题。
仍然对每个连通图任意建一棵生成树,我们发现麻烦的是多出来的边。
接下来说明一个事情:在连通图中,指定 \(k\) 个点的度数为奇数,当连通图中每个点的度数都有初始奇偶性(即度数可能不全为 \(0\))且 \(k\) 为偶数(存在答案的保证)时,仅通过连接生成树上的边,有且仅有一种连边方式满足指定条件。
对于确定的指定奇度数点集,不同的初始奇偶情况对应不同的仅考虑生成树上连边对每个点的度数贡献后每个点的奇偶情况。
说白了就是针对多出来的边把贡献抵消,转化成生成树上的连边问题。而这个问题在之前提到过,生成树上一定对应唯一满足的生成子图。这里给出证明思路:从叶节点开始考虑,每一步向父节点连的边的选择情况唯一确定。话已至此,觉得有个题在这个地方与本题有相似性:CF1554E。
可能说的不清楚,总之上面的事情是在说明:给定偶数 \(k\),无论生成树外的边怎么连,生成树上总有且仅有一种满足条件的连边方法。
所以方案数应为 \(\binom{|V|}{k}2^{|E| - |V| + 1}\)。
对于不连通的图,还需要用 dp 转移统计答案。
实现(直接组合式子做):预处理出每个块,设计 \(f_{i, j}\) 表示考虑前 \(i\) 个连通块内奇度数点数为 \(j\) 的方案数。
每次枚举一下 \(j\) 和偶数 \(k\)。
时间复杂度 \(O(n^2)\)。
ARC115E LEQ and NEQ(2363)
Problem
给定一个长度为 \(n\) 的序列 \(a_1,a_2,\cdots ,a_n\),输出满足如下条件的序列 \(x\) 的方案数:
- \(1\leq x_i\leq a_i\)
- \(x_i\neq x_{i+1}(1\leq i\leq n-1)\)
\(2\le n\le 5\times 10^5,1\le a_i\le 10^9\)
Solution 1
\(O(n\log{n})\)。
考虑一个最简单的 dp。
记 \(f[i][j]\) 表示考虑前 \(i\) 位,第 \(i\) 位为 \(j\) 的方案数。
显然有:
复杂度 \(O(n\max(a_i))\),直接裂开。值得一提的是,这个 dp 是可以优化成一维的。
那么我们不妨就把第一维忽略掉,只看 \(f_j\)。
不难发现,我们可以 对一个有限制的转移式进行分类讨论。
具体地,记前缀和 \(S = \sum\limits_{k = 1}^{a_{i - 1}}f_{k}\)。
\(\forall j \in [1, a_{i - 1}]\),\(f_{j}\) 变为 \(-f_{j}\)。
\(\forall j\in [1, a_{i}], f_{j} \leftarrow S\)。
\(\forall j\in (a_{i}, \infty)\),\(f_{j} = 0\)。
这个可以用线段树维护。
Solution 2
\(O(n)\)。
AC15 AGC036C GP 2(2357)
Problem
有一个序列 \(a_{1 \cdots n}\),初始时均为 \(0\)。每一次操作中,可以选择 \(i \ne j\),将 \(a_i\) 加上 \(1\),将 \(a_j\) 加上 \(2\)。操作共进行 \(m\) 次,求最终序列有多少种可能的情况。答案对 \(998244353\) 取模。
\(n \leq 10^6, m \leq 5 \times 10^5\)。
Solution
不考虑过程,直接分析什么样的数列是合法的结果数列。
- \(\sum\limits_{i = 1}^{n}a_i = 3m\)。
- \(\max\limits_{i = 1}^{n}a_i \le 2m\)。
- \(\sum\limits_{i = 1}^{n}[a_i \bmod 2] \le m\)。
最后对奇数个数限制的转化尤为巧妙。然后来计数:
枚举奇数个数 \(k\),考虑把这些奇数全部减去 \(1\),问题化为将 \(3m - k\) 分给 \(n\) 个位置,每个位置上分到的数均为偶数。
若 \(3m - k\) 为奇数,方案数为 \(0\)。
否则,设 \(3m - k = 2p\),则问题又可以化为将 \(p\) 个相同小球分给 \(n\) 个位置,无其他限制。 这是插板法的经典问题。
考虑选取奇数的位置和小球放置问题,枚举 \(k\) 时的方案数为 \(\binom{n}{k}\binom{p + n - 1}{n - 1}\)。
但是这样没有保证条件二。不难用容斥解决:强行钦定一个位置上的数 \(>2m\),用类似的方法,把这个位置减去 \(2m + 1\),又转化为把 \(m - 1\) 个相同小球分给 \(n\) 个位置的问题。该部分的方案数为 \(n\binom{m + n - 2}{n - 1}\)。
即:
其中 \(p = \frac{3m - k}{2}\)。
AC16 ARC028D 注文の多い高橋商店(2997)
Problem
给定 \(n\),\(m\)。有 \(n\) 种商品,编号从 \(1\) 到 \(n\),第 \(i\) 种商品最多能拿 \(a_i\) 个。
共 \(q\) 次询问。每次询问给定 \(k\),\(x\),求第 \(k\) 种商品 恰好 拿走 \(x\) 个的前提下,在 \(n\) 种商品中一共拿走 \(m\) 个商品的方案数。两种方案不同当且仅当存在一种商品在二方案中被拿走的个数不同。输出答案对 \(10^9+7\) 取模的结果。
-
\(1 \leq n,m,a_i \leq 2\times 10^3\)
-
\(1\leq k\leq n\)
-
\(1\leq x\leq a_k\)
Solution
可以当作 可撤销背包模板题。
强制第 \(k\) 种物品必须选 \(x\) 个,相当于求只考虑第 \(k\) 种之外的物品,总个数为 \(m - x\) 的选取方案数,然后这个是多重背包板子。
但是有多组询问。对于每个物品,预处理只考虑第 \(i\) 种之外的背包数组。这里考察了可撤销背包。
具体地:
记 \(f[i][j]\) 表示考虑前 \(i\) 种物品,共选择了 \(j\) 件物品的方案数。
这个过程不用枚举 \(k\),而转成前缀和优化,使朴素的 \(O(n^3)\) 多重背包降为 \(O(n^2)\)。空间上面其实也可以把第一位给砍掉。
可撤销背包中,删除一种物品有多种方法。
-
仿照上面的做法,倒着处理一遍 dp 数组 \(g\),统计答案时排除要求的物品即可。
由于查询时还要枚举左右物品的数量分配,因此时间复杂度为 \(O(nm + Qm)\)。
-
用生成函数表示多重背包的总方案数,即对于一种数量为 \(s\) 的物品,其贡献为 \(\sum\limits_{i = 0}^{s}x^{i}\),合起来的生成函数即为若干个分别的生成函数相乘。删除一种物品,即为除去该种物品对应的生成函数,多项式除法,但不用多项式工业,直接暴力即可,\(O(nm)\)。
-
采用分治思想,递归到叶节点表示删除该种物品。那么如果递归左边,右边就可以背包合并起来;反之。如此,每种物品会被合并 \(O(\log{n})\) 次,总时间复杂度为 \(O(nm\log{n})\)。
AC17 Span Covering(3012)
Problem
有一个区间 \([0, X)\),你有一个数组 \(L_1, L_2, \cdots, L_n\)。对于每个 \(i\),你可以选择一个整数 \(j\) 满足 \(0 \le j \le X- L_i\),并覆盖 \([j, j + L_i)\) 这个区间。问有多少种方案,使得整个区间都被覆盖,方案数对 \(10^9 + 7\) 取模。
- $ 1\ \leq\ N\ \leq\ 100 $
- $ 1\ \leq\ L_i\ \leq\ X\ \leq\ 500 $
Solution
由于放置线段的先后顺序不影响方案数的统计,因此 先将线段从小到大排序以便于转移状态 。
然后,放置一条线段,会出现以下情况:
- 独立成一段
- 包含在之前放置的某一条线段内
- 拼接两条线段成一条线段
- 与一条线段相交,且不出现情况 3
设 \(f_{i, j, k}\) 表示考虑前 \(i\) 条线段,组成 \(j\) 个连续段,覆盖长度为 \(k\) 的方案数。
放置时体现出一种 有限制的自由。
-
1:独立成一段:
\[f_{i, j + 1, k + L_i} \leftarrow (j + 1)f_{i - 1, j, k} \] -
2:包含在之前放置的某一条线段内:
\[f_{i, j, k} \leftarrow (k - j(L_i - 1))f_{i - 1, j, k} \] -
3:拼接两条线段成一条线段:
枚举两段中间的长度 \(l\),共有 \(j - 1\) 个空隙,对每个空隙有 \(L_i - l - 1\) 个位置:
\[f_{i, j - 1, k + l} \leftarrow (j - 1)(L_i - l - 1)f_{i - 1, j, k} \] -
4:与一条线段相交,且不出现情况 3:
枚举露在外面的长度 \(l\),对每条与当前线段相交的线段,都有 \(2\) 个相交的方向,因此有 \(2j\) 个位置。
\[f_{i, j, k + l} \leftarrow 2j\times f_{i - 1, j, k} \]
事实上,每次转移的时候判断 \(f_{i - 1, j, k}\) 是否为 \(0\),然后再决定是否转移,会减少无效状态对时间复杂度的影响,可以将 \(O(n^2X^2)\) 降为 \(O(nX^2)\)。
注意允许不放某些线段的情况。
还有就是,我们放置的时候需要用一条线段人为地把本来挨在一起但并没有被视作同一个段内的两条线段给拼接到一起,即此时属于情况 \(3\),\(l = 0\)。
ARC154E Reverse and Inversion(3506)
洛谷:ARC154E Reverse and Inversion
Atcoder:ARC154E Reverse and Inversion
Problem
给定一个长为 \(n\) 的排列,定义一次操作为:任取排列的一段区间,对这段区间进行翻转。
定义一个排列的权值为 \(\sum\limits_{i = 1}^{n}\sum\limits_{j = i + 1}^{n}(j - i)[a_{i} > a_{j}]\),即对于每个逆序对 \((i, j), i < j\),累计权值 \(j - i\)。
现在进行 \(m\) 次操作,求所有可能的最终序列的权值和。
\(1 \le n, m \le 2 \times 10^5\)。
保证输入数列是一个排列。
Solution 1
不使用 dp。
Solution 2
使用 dp。
AC19 ARC153F Tri-Colored Paths(3597)
Atcoder:ARC153F Tri-Colored Paths
Problem
给出一张 \(N\) 个点 \(M\) 条边的简单无向连通图。
你可以将分别每一条边染为 \(1,2,3\) 三种颜色之一。问不同的染色方案数,使得图中存在一条路径,其上同时存在三种颜色的边。答案对 \(998244353\) 取模。
- $ 3\ \leq\ N\leq\ 2\times\ 10^5 $
- $ 3\ \leq\ M\leq\ 2\times\ 10^5 $
- $ 1\ \leq\ A_i,\ B_i\ \leq\ N $
Solution
分类讨论。这题要多画图思考。
以图中存在 \(n\) 色环,对 \(n\) 的大小进行讨论。
不妨用总的染色方案 \(3^{m}\) 减去图中不存在满足条件的染色方案。
记后者为 \(cnt\),我们来数 \(cnt\)。
首先,我们可以轻松地得出整个图只有一种或两种颜色的方案。
于是我们只考虑整个图有三种颜色的方案。
\(n > 3\)
环长 \(> 3\),图中一定存在三色路径,因此对 \(cnt\) 没有贡献。
\(n = 3\)
当环长 \(> 3\) 时,断掉重复颜色的那条边,图中一定存在三色路径,对 \(cnt\) 无贡献。
所以只考虑三色三元环。
三元环连一条边时,那一条边的颜色只能为对边的颜色,且那一条边连出去的块内的边都只能为这个颜色。排列一下,有 \(6\) 种方案。
三元环连两条边且两条边的起点和终点不同时,一定存在三色路径。
难受的是存在这种情况:
幸运的是这种情况再连一条边就存在三色路径了,因此我们可以对 \(n\le 4\) 暴力统计。
\(n = 2\)
画图得知,异色边不论在环内外还是环内(此时异色边将环分成两个部分,且两个部分内的颜色相同),都会出现三色路径。
\(n = 1\)
考虑每一个割点,我们发现一个连通块内不能存在两种颜色的边。
注意我们有每种颜色的边都要出现的条件。
首先考虑以割点为根的一棵树,每个子树内不能存在异色边。假设子树内为同色边,此时将一条边变为异色边,如果这条边为连向树根的边,一条从叶节点到根的路径必然要经过此异色边;否则,从根定向走到那条异色边。而整个图存在三种颜色的边,因此在其余的子树内把剩下的一种颜色的边补上,就存在了一条三色路径。对于图,只需在树的基础上加上非树边即可,结论一样。
所以对于一个割点,统计其分出来的连通块数,分配连通块的染色方案,注意三种颜色都要出现。
具体来说,如果有 \(x\) 个连通块,那么对 \(cnt\) 的贡献为 \(3^x - 3\times 2^{x} + 3\)。
ARC155F Directable as Desired
AC21 ABC222H Beautiful Binary Tree(3477)
洛谷:ABC222H Beautiful Binary Tree
Atcoder:ABC222H Beautiful Binary Tree
Problem
定义大小为 \(n\) 的 Beautiful Binary Tree 为满足以下条件的有根二叉树:
-
每个节点 \(u\) 有一个初始权值 \(a_u\),为 \(0\) 或 \(1\)。
-
叶节点的初始权值必须为 \(1\)。
-
可以用至多 \(n - 1\) 次操作,使得根节点的权值为 \(n\) 且其余节点的权值为 \(0\)。其中一次操作定义为:
-
选择节点 \(u\) 和 \(v\),其中 \(u\) 需为 \(v\) 的父亲或祖父(父亲的父亲)。
执行 \(a_u \leftarrow a_u + a_v, a_v \leftarrow 0\)。
-
给定正整数 \(n\),求大小为 \(n\) 的 Beautiful Binary Tree 的数量。
\(1 \le n \le 10^7\)。
Solution
\(O(n^2)\)
首先,将操作转化为条件以方便计数。
我们可以分析出 Beautiful Binary Tree 需满足:
-
所有点的权值之和为 \(n\)。
-
叶节点的权值为 \(1\)。
-
根节点的权值为 \(1\)。
考虑达到最终状态需要将所有权值为 \(1\) 的位置上的 \(1\) 向上移动,而每次操作最多使已被操作的点中累计权值增加 \(1\),因此 \(n - 1\) 次操作最多使累计权值增加 \(n - 1\),那么根节点就必须有 \(1\) 的权值补上累计权值。
-
顺着上面的思路分析,我们发现每次必须要累计 \(1\) 点权值。
换句话说,一个节点 \(v\) 的二级祖先中必须有一个节点的权值为 \(1\),否则 \(a_v\) 贡献到 \(a_u\) 上不会有累计权值的改变。
这样看上去就比较好统计了。
记 \(a_i\) 表示大小为 \(i\) 的 Beautiful Binary Tree 的个数。
记 \(b_i\) 表示大小为 \(i\) 的二叉树个数。
该二叉树除了根节点为 \(0\) 不满足我们分析出来的 Beautiful Binary Tree 的性质,其他关于 Beautiful Binary Tree 的性质均满足。
则
其中,\(2a_i\) 表示根节点只有一个子节点时,有左右子节点两种情况。
\(\sum\limits_{0 < j < i}a_{j}a_{i - j}\) 则是有两个子节点时,对两侧的权值和进行分配。
我们再反过来表示 \(a\):
同样分为单子节点和双子节点考虑,意义比较显然,与上面类似。
于是可以 \(O(n^2)\) 递推出答案。但数据范围不允许我们这样就通过此题,于是展开了多项式工业。
\(O(n\log{n})\)
记 \(A(x)\) 与 \(B(x)\) 分别为数列 \(\{a_n \}\) 与 \(\{b_n \}\) 的普通生成函数。
回顾 OGF 的定义:
考虑将上面的 dp 转移式改写为 \(A,B\) 之间的关系:
于是 \(A(x) = x(1 + 3A(x) + A(x)^2)^2\)。
可以用牛顿迭代做到 \(O(n\log{n})\)。
\(O(n)\)
运用 拉格朗日反演。
由
可以设其复合逆为
此时有 \(G(A(x)) = x\)。则:
这是直接二项式系数暴力展开。
官方题解还给出了一种 dp 的方法:
记 \(T(x) = 1 + 3x + x^2\),\(m = 2n\),\(U(x) = T(x)^m\)。
借助 微分 的方法,我们可以找到如下关系:
记 \(u_k = [x^k]U(x)\),左右两侧得到的多项式均为 \(W(x)\)。记 \(w_k = [x^k]W(x)\)。
方便观察,我们将微分式表示成和式:
对左侧展开:\(w_{k}x^{k} = 1\times (k + 1)u_{k + 1}x^{k} + 3x\times ku_{k}x^{k - 1} + x^{2}\times (k - 1)u_{k - 1}x^{k - 2}\)。
对右侧展开:\(w_kx^{k} = m(3 \times u_{k}x^{k} + 2x\times u_{k - 1}x^{k - 1})\)。
于是得到:
由 \(u_0 = 1, u_{1} = 3m\),递推即可。最后带回 \([x^n]A(x) = \frac{1}{n}[x^{n - 1}](1 + 3x + x^2)^{2n} = \frac{u_{n - 1}}{n}\)。
ABC134F Permutation Oddness(2532)
Three Gluttons(3315)
AC24 ARC108D AB(1987)
Problem
现有一个初始字符串 \(s = AB\)。现在有一种操作为在两个字符之间插入一个字符,对 AA,AB,BA,BB
分别有给定的插入字符。保证字符集为 A,B
。问最后长度为 \(n\) 的字符串的方案数。答案对 \(10^9 + 7\) 取模。
- \(2 \le n \le 1000\)。
Solution
由于操作集很小,不妨直接 分类讨论。
\(c_{AB} = B\) 时:
-
\(c_{BB} = B\) 时:答案为 \(1\),因为每次都只能插入 \(B\)。
-
\(c_{BB} = A\) 时:
-
\(c_{BA} = A\) 时:在创造出 \(ABB\) 之后,每次插 \(A\) 或 \(B\) 都可以,因此答案为 \(2^{n - 3}\)。
-
\(c_{BA} = B\) 时:发现合法串中不可能出现 \(AA\)。
设 \(f_{i, A/B}\) 表示长度为 \(i\) 且以 \(A/B\) 结尾的合法串长度。则:
\[\begin{aligned} f_{i, A} &= f_{i - 1, B} \\ f_{i, B} &= f_{i - 1, A} + f_{i - 1, B} \end{aligned} \]将第一个式子代入第二个式子,即得:
\[f_{i, B} = f_{i - 2, B} + f_{i - 1, B} \]再观察原串,发现最终结果一定以 \(AB\) 开头,以 \(B\) 结尾。
中间能填的正好是所有不包含 \(AA\) 的串。
因此有 \(f_{0} = 1, f_{1} = 2, ans = f_{n - 3}\)。
-
\(c_{AB} = A\) 的情况类似,故不再赘述。
AC25 ARC108F Paint Tree(2646)
Problem
给定一棵 \(n\) 个节点的树。你需要对每个节点黑白染色。
设 \(x\) 表示白色点之间的最大距离,\(y\) 表示黑色点之间的最大距离,那么定义一种染色的权值为 \(\max(x,y)\)。如果某种颜色没有出现那么对应的 \(x/y\) 就是 \(0\)。
求所有 \(2^n\) 种染色方式的权值和。对 \(10^9+7\) 取模。
\(\texttt{Data Range:} 2\le n\le 2\times 10^5\)。
Solution
先送一个官方题解。
Let D be the diameter of the tree and x,y be the endpoints of the diameter.
If x and y are of the same color, the niceness is obviously D. Below, we only consider the case x is white and y is black. An important fact is that there is a white vertex whose distance from x is X. The same goes for y and Y. We can prove this from the fact that x and y are the endpoints of the diameter.
Thus, Only the distances from x and y matter; the distances between the other vertices do not matter. From here, we can see the following: if there is a vertex whose distances from x and y are both greater than d, there is no way of painting the tree with niceness at most d; otherwise, there are 2^k such ways, where k is the number of vertices whose distances from x and y are both at most d.
Using these, we can find the total niceness of all ways of painting the tree. It can be done in O(N) time, which is fast enough.
所有的染色中,不同的贡献数是 \(O(n)\) 级别的,我们可以考虑枚举贡献然后去数一个贡献对应的染色数。
首先考虑最特殊的情况:树的直径链上两端点节点颜色相同。此时单个染色的贡献即为树的直径 \(D\)。
记树的直径链两端点分别为 \(S\) 和 \(T\)。
由于染色数要乘上贡献的权值,因此,不妨在枚举、统计时,计算 \(\max(x, y) > i\) 的染色数,我们发现这样会更方便数数。于是我们只用枚举 \(i < D\),因此接下来的分析均以 \(S\) 与 \(T\) 异色。
记 \(ds_u\) 为 \(u\) 到 \(S\) 的距离,\(dt_u\) 为 \(u\) 到 \(T\) 的距离。
记 \(d = \max(\min(ds_u, dt_u))\),对于所有 \(< d\) 的 \(i\),由于不存在 \(\max(x, y) < d\) 的染色方案,因此这些 \(i\) 的贡献即为 \(2^n\)。
当 \(d \le i < D\) 时:考虑容斥,用总染色数 \(2^n\) 减去 \(\max(x, y) \le i\) 的染色数。
考虑每一个点对答案可能的贡献,可能的最大贡献即为 \(\max(ds_u, dt_u)\)。如果存在一个点使得 \(\max(ds_u, dt_u) > i\),那么这种染色就应该被计入当前枚举的 \(i\) 对应的染色数中;然而我们现在要找的是不合法的染色方案,用总方案去减掉这部分的数量。
发现当 \(\max(ds_u, dt_u) \le i\) 时,点 \(u\) 的染色一定不会 决定 产生 \(> i\) 的贡献。
记这种点的数量为 \(cnt_i\),则不合法的染色数为 \(2^{cnt_i + 1}\)。对于 \(\max(ds_u, dt_u) \le i\) 的点,任意染色;否则,只能根据两端点的染色情况尽可能让 \(u\) 靠近同色的一端,即令其贡献为 \(\min(ds_u, dt_u)\)。由于 \(i \ge d = \max(\min(ds_u, dt_u))\),因此取 \(\min(ds_u, dt_u)\),一定 \(\le i\),保证了总有一种且仅有一种对这部分点的染色方案使总染色方案不合法。至于 \(2^{cnt_i + 1}\) 中的 \(+1\),是对两端点的颜色进行分配。
于是这题就分析完了。