做计数题的一些记录

做计数题的一些记录

  • [x] TC-TriangleTriples(5.22)
  • [x] CodeChef-TREECNT2(5.22)
  • [x] CF838D-Airplane Arrangements(5.24)
  • [x] CSA-cube coloring(5.24)
  • [x] CodeChef-TREDEG(5.25)
  • [x] ARC093F-Dark Horse(5.30)
  • [x] CSA-colored forests(5.30)
  • [x] CSA-Sum of Squares(5.31)
  • [x] CF755G-PolandBall and Many Other Balls(6.3)
  • [x] CF1153F-Serval and Bonus Problem(6.4)

T10

Problem

有一段长为 (l) 的线段,有 (n) 个区间,左右端点在 ([0,l)) 间均匀随机(可能不是整数)。求期望被至少 (k) 个区间覆盖的长度,对 (998244353) 取模。

(1leq kleq nleq 2000,lleq 10^9)

Solution

挺巧妙的一道题,和求 (n) 个变量中的第 (k) 小期望的值用的技巧是一样的。

首先 (l) 是可以暂时忽略的,只需要解决长度为 (1) 的线段,即求出概率,再把答案乘上 (l) 即可。

把线段的两端视作两个球,分别表示 (+1)(-1),序列上大于等于 (k) 的位置即表示被覆盖至少 (k) 次。由于一个球在区间上的分布是均匀的,那么我们就可以引入一个观察球,转而求观察球出现在大于等于 (k) 的位置的概率,可以通过求方案数来解决。

(f[i][j][0/1]) 表示前 (i) 个位置,用了 (j)(+1) 且是否放置观察球的方案数,由记录的状态可以算出当前位置上的值。那么只需要枚举当前位置放什么类型的球即可。

时间复杂度 (O(n^2))

T9

Problem

(n) 个不同的球,一个盒子要么放一个球,要么放两个相邻的球。设 (Q(m)) 表示恰好装 (m) 个盒子的方案数。给定 (k) ,求所有的 (Q(m),min [1,k])

(nleq 10^9,k< 2^{15})

Solution

(f[i][j]) 表示长度为 (i) 的球中选 (j) 组的方案数

(f[i][j]=f[i-1][j]+f[i-1][j-1]+f[i-2][j-1])

考虑DP快速幂,那么需要讨论中间拼接的两个相邻的球会不会选

[f[x+y][i]=sum_{j+k=i} f[x][j]cdot f[y][j]+sum_{j+k=i-1} f[x-1][j]cdot f[y-1][k] ]

维护 (f[i],f[i-1],f[i-2]) 即可倍增,合并时用NTT优化。这样的复杂度为 (O(klog k log n))

(k) 应该出到 (2^{17}),否则可能会被 (O(k^2)) 的暴力水掉很多分。

T8

Problem

给定 (n,k),设一个长度为 (k) 的正整数不严格递增数列 ({a_i}) 的贡献为 (sum_{i=1}^k a_i^2),求所有不同的数列的贡献和。

(kleq nleq 10000)

Solution

这题的技巧其实在于状态的设计上。一个不严格递增数列其实也可以通过每次给长度不严格递增的后缀增加 (1) 来实现,不难证明每个数列有且仅有一种实现方法。

不妨考虑给一个长度为 (l) 后缀增加 (1) 时带来的增量:

[sum_{i=1}^l ((a_i+1)^2-a_i)=sum_{i=1}^l (2a_i+1) ]

(f[i][j]) 表示最后一次是给长度为 (i) 的后缀作加法,此时所有元素之和为 (j) 的状态,记录状态的方案数即可通过增量来计算贡献和。每次可以不再做加法,转移到 (f[i+1][j]),也可以做一次转移到 (f[i][j+i])

这样我们也可以通过当前状态记录的两维来推算新增的贡献了,注意数列中不能存在 (0),不难发现所有的非法状态必有 (a_1=0),即对应了 (f[k-1][n])。时间复杂度 (O(nk))

T7

Problem

(m) 种颜色,每个节点可以染一种颜色,定义一棵树是彩色的,当且仅当这棵树上出现过所有的颜色。求有 (1sim n) 个节点的不同森林个数。

(nleq 10^5,mleq 50)

Solution

首先对于一个 (i) 个节点的树,涂色的方案就是 (i) 个球放入 (m) 个不同的盒子的方案数,即 (S_2(i,m)m!)

(f_i) 表示有 (i) 个节点的森林个数,(T_i) 表示 (i) 个节点的树的个数,由prufer编码可以知道 (T_1=1,T_i=i^{i-2}(i>1))。但是如果直接这么转移

[f_i=sum_{j=1}^iinom i jf_{i-j}S_2(j,m)m!T_j ]

是会有重复计数的,即当前森林有多少棵树就会算多少的阶乘次。这里用到的技巧是 (j) 枚举的是节点 (i) 所在的树的大小。

[f_i=sum_{j=1}^i inom {i-1} {j-1} f_{i-j} S_2(j,m)m!T_j ]

把式子拆开得到

[f_i=(i-1)!sum_{j=1}^i frac {f_{i-j}} {(i-j)!}cdot frac {S_2(j,m)m!T_j} {(j-1)!} ]

不方便转为多项式求逆的形式,所以直接分治NTT即可做到 (O(nlog^2 n+nm))

T6

Problem

(2^n) 个人,从 (1) 开始编号。若编号为 (x)(y) 的人比赛,那么编号较小的人会胜利。但是有 (m) 组例外,当 (1)(a_i) 比赛时,(a_i) 会胜利。

现在把所有的人排列起来,进行淘汰赛,即排列中第一个和第二个比赛,第三个和第四个比赛……获胜的人再按原来的先后顺序站。

问有多少中排列方式使得 (1) 是最后的获胜者。

(1leq nleq 16,0leq mleq 16)

Solution

淘汰赛就是一个类似线段树的结构,只有 (1) 到根的路径上会有不同。考虑我们其实就是每次和长度为 (2^0,2^1,cdots,2^{n-1}) 的区间合并,这个区间的获胜者是区间最小值。问题就是统计有多少种方案使得各个区间的最小值都不是 (a_i) 中的数。

考虑容斥,枚举这些不合法的区间的集合 (S),使其他区间随便乱排。那么显然 (ans=sum_{S}(-1)^{|S|}g[S])

计算 (g[S]) 可以用状压dp,枚举 (a_i) 出现在哪个区间中,由于我们希望知道有哪些数字是可以选的,因此按照 (a_i) 从大到小进行枚举,这样之前用过的数字都比之前枚举过的 (a_j(a_j>a_i)) 大,这些数在此时也用不了。

时间复杂度 (O(2^n+nm2^n))

T5

Problem

设一棵树的权值为各个点的度数乘积的 (K) 次方,求随机一棵树的期望权值为多少?若两棵树不同,则存在 (u,v) 使得在一棵树中它们有边,另一棵没有。

(K=1)(sum nleq 2 imes 10^6)(K>1)(sum nleq 10^5)

Solution

根据prufer编码,不难设计出 (f[i][j]) 表示考虑前 (i) 个点,序列长度为 (j) 的方案数

[f[i][j]=sum_{r=0}^j inom j r f[i-1][j-r] (r+1)^K ]

[frac {f[i][j]} {j!}=sum_{r=0}^jfrac {f[i-1][j-r]} {(j-r)!}cdot frac {(r+1)^K} {r!} ]

不妨设 (A(x)=sum_{i=0}^infty frac {(i+1)^K} {i!} x^i) ,答案就是 (A^n(x)) 的第 (n-2) 项系数。

(K>1) 时直接暴力NTT快速幂即可做到 (O(nlog^2 n))

(K=1)

[A(x)=sum_{i=0}^infty frac {i+1} {i!} x^i=sum_{i=1}^infty frac {1} {(i-1)!} x^i+sum_{i=0}^infty frac 1 {i!} x^i=(x+1)e^x ]

[A^n(x)=(x+1)^ne^{nx}=iggl(sum_{i=0}^n inom n i x^iiggr)iggl(sum_{i=0}^inftyfrac {n^i} {i!}x^iiggr) ]

暴力算是 (O(n)) 的。

T4

Problem

(n) 种颜色,第 (i) 种颜色可以用 (c_i) 次。现在想要给一个正方体的六面涂色,要求有公共棱的两面颜色不同,旋转判定同构。求染色方案数。

(nleq 1000)

Solution

由于相邻两面颜色不同,所以每种颜色至多用2次,因此仅有4种情况,即六种颜色染1面,一种染2面+四种染1面,两种染2面+两种染1面,三种染2面。而这些情况分别有30,3,1,1种染色方法。

对于六种颜色染1面的计数方法是,一共24种旋转方法,所以就是 (frac {6!} {24}=30) 种。

选颜色用组合数算一下即可。(O(n))

T3

Problem

(n) 个座位和 (m) 个人,每个人会选择一个目标位置 (i) 并且选择从前向后或从后向前走。人会先走到目标位置,没人就坐下来,否则继续走到第一个空位置坐下来。

若有人走到末尾都没有座位,他就会不满意。求每个人都满意的方案数,对 (10^9+7) 取模。

(mleq n leq 10^6)

Solution

人类智慧题,考虑加第 (n+1) 个位置并把座位搞成一个环,这样只要第 (n+1) 个座位为空即说明每个人都满意,而环上座位都是等价的,即每个座位为空的概率相同,因此只需要求出全集即可。

(O(log n))

T2

Problem

有一棵 (n) 个节点的树,边上带边权,有 (Q) 次修改操作,每次修改一条边的边权,求修改完后有多少个无序二元组 ((x,y)) 满足它们路径的 (gcd=1)

(nleq 10^5,Qleq 100,w_ileq 10^6)

Solution

先考虑一次询问怎么做,可以容斥,设 (f(i)) 表示路径公约数是 (i) 的倍数的方案数,则答案为 (sum_{i=1}^{10^6} mu(i)f(i))。求 (f(i)) 可以用并查集维护联通块,一个联通块中任选两个点均合法。一次的复杂度为 (O(wlog n))

注意到询问组数很少,不妨考虑直接把各组询问一起计算贡献,那么用可删除的并查集,枚举 (i) 时暴力维护联通块即可。

时间复杂度 (O((w+q^2)log^2 n))

T1

Problem

给定 (A,B,C),问有多少个有序三元组 ((a,b,c)) 使得 (aleq A,bleq B,cleq C) 且它们可以组成三角形,模 (10^9+7)

(A,B,Cleq 10^9)

Solution

我们可以计算不合法的方案数,枚举哪两条边的和小于等于第三条,用 (f(A,B,C)) 表示 (a+bleq c,aleq A,bleq B,cleq C) 的方案数。

则答案就是 (ABC-f(A,B,C)-f(B,C,A)-f(C,A,B))

(f()) 考虑用容斥来计算。设 (g(x)) 表示 (a+bleq cleq x) 的方案数,发现 (g(C))(f(A,B,C)) 多统计了 (a>A,b>B) 的情况。考虑 (a>A) 的情况,令 (a'=a-A,c'=c-A) 则它的方案数就等价于 (a'+bleq c'leq C-A) 的方案数,即 (g(C-A))。如法炮制,容斥一下,则有

[f(A,B,C)=g(C)-g(C-A)-g(C-B)+g(C-A-B) ]

[g(x)=sum_{i=1}^x(i-1)(x-i+1)=sum_{i=1}^x(-i^2+(2+x)i-(x+1)) ]

用公式即可 (O(1)) 计算。

原文地址:https://www.cnblogs.com/totorato/p/12905942.html