20240820:组合计数(2)

组合数#

定义:(nm) 表示 n 元集的 m 元子集个数。

通项#

(nm)={n!m!(nm)!mn0otherwise

考虑其组合意义:

把所有 n! 个排列的前 m 个元素作为选出集合,每个集合被计算 m!(nm)! 次。

二项式定理#

(x+y)n=i=0n(ni)xiyni

组合意义:从 n 个括号里选出 i 个给 x,剩下给 y

因此第 n 行组合数的普通生成函数 Fn(x) 的封闭形式为:

Fn(x)=i=0n(ni)xi=(x+1)n

组合数的对称性#

(nm)=(nnm)nm0

组合数的吸收公式#

(nm)=nm(n1m1)n,m>0

递推公式#

(nm)=(n1m)+(n1m1)

组合意义就是讨论第 n 个元素是不是选出的第 m 个元素。

从生成函数的角度理解:Fn(x)=(x+1)Fn1(x),对比系数得到递推公式。

组合数的行和#

i=0n(ni)=(1+1)n=2ni=0n(ni)(1)i=(11)n=[n=0]

组合数的列和#

i=0n(im)=(n+1m+1)

把和式中第一个非零项 (mm) 看作 (m+1m+1)

  • (m+1m+1)+(m+1m)=(m+2m+1)
  • (m+2m+1)+(m+2m)=(m+3m+1)

以此类推得到 (nm+1)+(nm)=(n+1m+1)

范德蒙德卷积#

i=0k(ni)(mki)=(n+mk)

n+m 元集拆成一个 n 元集和一个 m 元集。

枚举 n+m 里面选 k 个出来的所有方案与这个 n 元集的交集 i,组合意义显然。

一个很有用的公式#

(nm)(mr)=(nr)(nrmr)

n 个里面选 m 个,再在 m 个里面选 r 个。

等价于 n 个里面选 r 个,在剩下的 nr 个里再选 mr 个。

容斥原理#

|i=1nSi|=1x1<x2<xmn(1)m1|i=1mSxi|

考虑每个元素在右式被计算几次。

如果一个元素在 kSi 中出现,那么他会被计算 i=1k(1)i1(ki)=[k0]

因此左边等于右边。

很多情况下要求同时满足 n 个条件的集合大小。

Si 为不满足第 i 个条件的集合,那么答案即 |U||i=1nSi|

无限制的格路计数#

题意:给定 n,m0,你一开始在原点,每次可以从 (x,y) 走到 (x+1,y+1)(x+1,y1),问走到 (n,m) 的合法方案数。

设往右上走了 t 步,则往右下走了 nt 步。

解方程 t(nt)=mt=n+m2

如果 2n+m,那么方案数为 0,否则方案数为 (nn+m2)

从生成函数的角度理解,次数代表纵坐标:

[xm](x+x1)n=[xn+m](x2+1)n=(nn+m2)

反射容斥#

例1:给定 n,m0 以及 p<0,你一开始在原点,每次可以从 (x,y) 走到 (x+1,y+1)(x+1,y1)

问不经过直线 y=p 上的点走到 (n,m) 的合法方案数。

考虑用上个模型的方案数减去经过 y=p 的方案数。

对于一个经过 y=p 的方案,我们将 p 上方的路径折下来,得到一条 (0,2p)(n,m) 的路径,任意新路径都能翻回去,因此这是一个双射。

则合法方案数等于 (nn+m2)(nn+m2p2)

例2:给定 n,m0 以及 p<0, q>m,你一开始在原点,每次可以从 (x,y) 走到 (x+1,y+1)(x+1,y1)

问不经过直线 y=py=q 上的点走到 (n,m) 的合法方案数。

还是用总方案减去不合法的方案,问题转化为经过 y=py=q 走到终点的方案数。

对于一条路径,如果经过 y=p 就写 'A',经过 y=q 就写 'B',如图路径写成 "BBBBAAB"。

把连续相同字符缩成一个,即 "BAB"。

每个路径都可以映射成一个字符串,字符串 “AB” 表示一条先经过 y=p 再经过 y=q 的路径,且没有其他地方与限制相交。

钦定先经过 y=p 再经过 y=q 的方案如何求?先将起点延 y=p 翻折转化为只有一条限制的情况,再延 y=q 翻折。

恰好呢?考虑上述计算方式会多计算哪些情况?

所谓 "AB",我们在计算过程中并不关心 "A" 前面有没有 "B" 以及 "B" 后面有没有 "A", "AB", "ABA"...。

也就是说,"BAB", "BABA"... 和 "ABA", "ABAB"... 都会在计算 "AB" 时被算到。

如何构造容斥系数使得每种非法情况("A", "B", "AB", "BA", "ABA"...)最后计算次数恰好为 1

从另一个角度考虑重复计算,如果 TS 的子串,那么 S 的所有路径会在计算 T 时恰好被算一次。

对于字符串 "ABABA",其本质不同子串有 "A", "AB", "ABA", "ABAB", "ABABA", "B", "BA", "BAB", "BABA"。共 2|S|1 个。

我们知道 i=12|S|1(1)i=1,因此把每种字符串的容斥系数定为 (1)|S| 可以恰好满足条件。

由于每增加一个字符,横坐标就要增加至少 qp 的长度,需要考虑的字符串只有 O(nqp)(不考虑从原点第一次到限制的距离,反正就是很少)。

卡特兰数#

定义:第 n0 项卡特兰数 Cn 表示长度为 2n 的合法括号序列数。

通项#

Cn=(2nn)(2nn+1)

用反射容斥解释这个式子。

左括号表示 (x,y)(x+1,y+1),右括号表示 (x,y)(x+1,y1),卡特兰数等于 (0,0) 走到 (2n,0) 不经过 y=1 的路径数。

这样映射满足了合法括号序列的充要条件:左括号 = 右括号;任意前缀左括号不小于右括号。

递推式#

枚举第一个右括号之间有多少括号对:

Cn=i=0n1CiCni1

通过递推式解得卡特兰数的生成函数

F(x)=xF(x)2+1F(x)=114x2x

子集反演#

f(S)=TSg(T)g(S)=TS(1)|S||T|f(T)f(S)=STUg(T)g(S)=STU(1)|T||S|f(T)

只考虑第一个式子,第二个类似。

从左推右:

g(S)=TS(1)|S||T|f(T)=TS(1)|S||T|RTg(R)=RSg(R)TSR(1)|S||TR|

h(S)=TS(1)|S||T|

h(S)=TS(1)|S||T|=i=0|S|(1)|S|i(|S|i)=[S=]

带回原式:

g(S)=RSg(R)h(SR)=g(S)

从右推左:

f(S)=TSg(S)=TSRT(1)|T||R|f(R)=RSf(R)TSR(1)|T|=RSf(R)[SR=]=f(S)

二项式反演#

引入#

错排问题:n 个人排列。第 i 个人不能在位置 i,求合法排列数。

钦定 k 个人在自己位置上:

k=0n(1)k(nk)(nk)!

定义 f(n)n 个人的排列数,g(n)n 个人的错排数。

f(n)=k=0n(nk)g(k)g(n)=k=0n(1)nk(nk)f(k)

问题在于 f 能够快速计算,如何通过 f 反求 g

有组合恒等式

k=0n(1)k(nk)=[n=0]

说一句废话:

g(n)=m=0n[nm=0](nm)g(m)

[nm=0] 用上面的恒等式带掉:

g(n)=m=0nk=0nm(1)k(nmk)(nm)g(m)=m=0nk=0nm(1)k(nk)(nkm)g(m)=k=0n(1)k(nk)m=0nkg(m)(nkm)=k=0n(1)k(nk)m=0nkg(m)(nkm)=k=0n(1)k(nk)f(nk)=k=0n(1)nk(nk)f(k)

公式#

f(n)=i=0n(ni)g(i)g(n)=i=0n(1)ni(ni)f(i)f(n)=i=nU(in)g(i)g(n)=i=0n(1)in(in)f(i)

可以理解为 g(S) 只与 |S| 相关的子集反演。

实际应用中一般用第二种形式,f(n) 表示钦定 n 个的方案数,g(n) 表示恰好 n 个的方案数。

莫比乌斯反演#

引入#

周期问题:求长度为 n 的字符串且周期(最小循环节)恰为 n 的字符串个数,仅包含小写字母。

定义 f(n) 为长度为 n 的字符串个数,g(n) 为长度为 n 且周期恰为 n 的方案数。

f(n)=dng(n)

显然有 f(n)=26n,怎么反求 g

设函数 μ 满足

dnμ(d)=[n=1]

构造一句废话然后代入:

g(n)=mn[nm=1]g(m)=mndnmμ(d)g(m)=dnμ(d)mndg(m)=dnμ(d)f(nd)=dnμ(nd)f(d)

公式#

f(n)=ing(i)g(n)=inμ(ni)f(i)f(n)=ni, iUg(i)g(n)=ni, iUμ(in)f(i)

从子集反演的角度理解这个公式。

把每个数 x 映射成一个无限长的向量,第 i 为表示正整数中第 i 个质数在 x 中的次数。

整除关系即集合之间的包含关系。

现在目的是从 f(n) 里面减掉没有顶满(因子)的方案数。

只容斥与原数高度相差 1 的因子,减掉所有的 f(npi),加上所有 f(npipj),以此类推。

这同时也与 μ 函数对应:存在平方因子(差两格)则为 0;否则为 1 的质因子个数次方。

第二类斯特林数#

{nm} 表示把 n 元集划分为 m 个互不区分的非空集合的方案数。

通项公式#

先假定 m 个集合互相区分,最后除以 m!

钦定部分集合为空,然后容斥。

{nm}=1m!i=0m(1)m(mi)(mi)n

递推式#

{nm}=m{n1m}+{n1m1}

考虑最后一个元素 n 扔到哪里。

选一个现有集合扔进去(虽然集合互不区分,但是元素互不相同);新增一个集合。

普通幂转下降幂#

xn=i=0x{ni}xi

xn 表示 n 个元素分配给互相区分的 x 个集合的方案数。

选出 i 个集合,n 个元素分出 i 个非空集合的方案是 s(n,i),由于集合不区分,再乘一个 i!

单位根反演#

单位根:xn=1 在复平面上的 n 个解,其中 wnk=ei2kπn

[nk]=1ni=0n1wnik

nk 时,wnik=1,右式等于 1

否则右边是一个等比数列,等于 1n×1wnnk1wnk=0

用于模意义下的原根也是对的。

min-max 容斥#

min(S)==TS(1)|T|1max(T)max(S)==TS(1)|T|1min(T)

以第一种形式为例,第 k 小的元素被计算的次数等于:

i=1k(k1i1)(1)i1=i=0k1(k1i)(1)i=[k=1]

实际应用一般结合期望,也就是如果一个集合的期望最小不好求,可以去求他的期望最大。

高维前缀和#

二维前缀和:

for(int i = 1; i <= n; ++ i) {
    for(int j = 1; j <= n; ++ j) {
        a[i][j] += a[i - 1][j];
	}
}
for(int i = 1; i <= n; ++ i) {
    for(int j = 1; j <= n; ++ j) {
        a[i][j] += a[i][j - 1];
	}
}

三维前缀和:

for(int i = 1; i <= n; ++ i) {
    for(int j = 1; j <= n; ++ j) {
        for(int k = 1; k <= n; ++ k) {
			a[i][j][k] += a[i - 1][j][k];
        }
	}
}
for(int i = 1; i <= n; ++ i) {
    for(int j = 1; j <= n; ++ j) {
        for(int k = 1; k <= n; ++ k) {
			a[i][j][k] += a[i][j - 1][k];
        }
	}
}
for(int i = 1; i <= n; ++ i) {
    for(int j = 1; j <= n; ++ j) {
        for(int k = 1; k <= n; ++ k) {
			a[i][j][k] += a[i][j][k - 1];
        }
	}
}

子集和:

用偏序的形式表示子集和,可以发现他就是一个 n 维,每个维度只有 01 的前缀和。

TSaT=T1S1T1S1TnSnaT

for(int i = 0; i < n; ++ i) {	// 枚举维度,1011 用数组表示为 a[1][1][0][1]
    for(int s = 0; s < 1 << n; ++ s) {
        if(s >> i & 1) a[s] += a[s ^ 1 << i];
	}
}

子集和还有分治做法。

对于一个 [0,2n) 的序列,每次把他分成两部分 [0,2n1)[2n1,2n)

递归处理每个数在各自分治区间的子集和。

考虑合并两部分信息。

右边部分的第 n1 位都是 1,左边部分的第 n1 位都是 0,对应位呈现包含关系(x 对应 x+2n1)。

因此右边再加上左半边对应的贡献就可求得当前分治区间的子集和。

时间复杂度 T(2n)=2T(2n1)+O(2n)=O(n2n)

快速莫比乌斯变换#

集合幂级数 F(x) 的莫比乌斯变换 F^(x) 满足:

[xS]F^(x)=TS[xT]F(x)

莫比乌斯变换即高维前缀和。

莫比乌斯逆变换即高维差分,都可以按维 dp 做到 O(|U|2|U|)

集合并卷积(或卷积)#

求集合幂级数 H(x)=F(x)G(x),满足

[xS]H(x)=TR=S[xT]F(x)[xR]G(x)

先求出 H^(x),再做逆变换。

[xS]H^(s)=TRS[xT]F(x)[xR]G(x)=TS[xT]F(x)RS[xR]G(x)=[xS]F^(x)[xS]G^(x)

推广:集合交卷积(与卷积)

同样令 H^(x) 表示 H 的变换:

[xS]H^(s)=STR[xT]F(x)[xR]G(x)=ST[xT]F(x)ST[xR]G(x)=[xS]F^(x)[xS]G^(x)

类似的,只不过是高维前缀和换成高维后缀和。

集合无交并卷积(子集卷积)#

[xS]H(x)=TR=S, TR=[xT]F(x)[xR]G(x)

考虑在集合幂级数中引入未定元 y,指数代表集合大小。

x 做集合并卷积,y 做乘法卷积,求得 H(x,y)=F(x,y)G(x,y),其中 [xSy|S|]F(x,y)=[xS]F(x)

两个集合无交当且仅当 |ST|=|S|+|T|

因此有 [xS]H(x)=[xSy|S|]H(x,y)

我们把形式幂集数 F(x,y) 看作一个 |U|2|U| 的二维矩阵。

每一行保留大小为 i 的集合系数,其余全为 0

|U|2 枚举 FG 的行,然后做两行的集合并卷积,时间复杂度 |U|32|U|

考虑 |U|22|U| 预处理出每一行的莫比乌斯变换,暴力算 y 卷积时只要 O(|U|) 对应系数相乘。

莫比乌斯变换是线性变换,不需要每做一次卷积就要逆变换,系数可以累加。

最后对每一行做莫比乌斯逆变换,时间复杂度 O(|U|22|U|)

快速沃尔什变换#

[xS]H^(x)=TU(1)|ST|[xT]F(x)

  • 注意 T 的范围是所有集合。

考虑分治。

对于 [0,2n) 的区间,划分为 [0,2n1)[2n1,2n) 两个子问题。

x 原来的系数为 f(x),考虑跨块贡献后的新系数为 f(x)

对于一个右侧元素 x+2n+1,左侧对他的贡献怎么算?

发现左侧对 x+2n+1 的贡献和原来对 x 的贡献(即 f(x))是一样的,因为左边第 n1 位都为 0

右侧元素对 x+2n+1 是否还是 f(x+2n+1)

[2n1,2n) 里做 FWT 时没有考虑第 n1 位的贡献,因此 f(x+2n1)=f(x)f(x+2n1)

类似地考虑左半边,f(x)=f(x)+f(x+2n1)

沃尔什逆变换#

试着对 F^(x) 再做一遍沃尔什变换。

[xS]F^^(x)=TU(1)|ST|RU(1)|TR|[xR]F(x)=RU[xR]F(x)TU(1)|(SR)T|=RU[xR]F(x)TU(1)|(SR)T|=RU[xR]F(x)i=0|SR|(|SR|i)2|USR|=RU[xR]F(x)2|U|[S=R]=2U[xS]F(x)

第二步中 表示对称差。SR 的公共元素会对 1 产生偶数次贡献。

我们发现只要将 F^^(x) 的各项系数乘上 12|U| 即可还原 F(x),即沃尔什逆变换。

集合对称差卷积(异或卷积)#

H(x)=F(x)G(x)

[xS]H^(x)=TS(1)|ST|[xT]H(x)=TS(1)|ST|LR=T[xL]F(x)[xR]G(x)=L,R(1)|S(LR)|[xL]F(x)[xR]G(x)=L(1)|SL|[xL]F(x)R(1)|SR|[xR]G(x)=[xS]F^(x)[xS]G^(x)

burnside 引理#

对于一个群 (G,×),里面的元素都是作用于集合 X 的置换。

h=f×gxX, h(x)=g(f(x))

(G,×) 是群需要满足:

  1. a,bG, a×bG
  2. a,b,cG, (a×b)×c=a×(b×c)
  3. eG, aG, e×a=a×e=a
  4. aG,bG, a×b=e,把 b 称作 a 的逆元。

如果 X 中两个元素可以通过 G 中置换变得相等,那么称他们等价,同属一个等价类。

X 中的等价类个数等于

1|G|gGxX[g(x)=x]

拉格朗日插值#

假设已知多项式 f(x)n 处点值 (xi,yi),可以构造出满足这些点值限制的多项式:

g(x)=i=1nyijixxjxixj

如果 f(x) 次数小于 n,根据代数基本定理可知 f(x)=g(x)(我不会证)。

这意味着我们只需 n 个点值就能确定 f(x)

点值表示做乘法时只有 O(n) 而非卷积的 O(n2)

通过点值还原 f(x) 可以先 O(n2) 求出 xxj,然后对于求和的每一项 O(n) 除一个一次多项式即可。

CF722E Research Rover#

题意:n×m 的网格,图上 k 个关键点。给定初始权值 s,每经过一个关键点权值减半(上取整)。

每次只能向右或向下走,求从 (1,1) 走到 (n,m) 的期望权值。

将关键点排序。

最终权值只与经过的关键点数有关, fi,j 表示走到第 i 个关键点恰好选了 j 个的方案数。

不怎么好转移,定义 gi,j 表示走到 i 个关键点至少走了 j 个的方案数。

gi,j=l=0i1gl,j1(xixl+yiylxixl)fi,j=gi,jgi,j+1

由于我们将方案根据恰好经过的第 j1 个关键点进行分类,因此求得的 g 是不重不漏的。

j>20 时权值一定削减为 1,因此只需算到 j=20,剩下的贡献用总方案减掉即可。

submission

CF1097G Vladislav and a Great Legend#

题意:给定一颗 n 个节点的树 T,对应任意非空顶点集 Xf(X) 定义为它在原图的极小连通子图中的边数,求:

X{1,2,,n}f(X)k

其中 n105, k200,极小连通子图可认为是保留所有边的虚树。

X{1,2,,n}f(X)k=i=0k{ki}i!X(f(X)i)

(f(X)i) 的组合意义是从 X 的虚树中选 i 条边的方案数。

枚举虚树根 x 统计贡献。现在加入一颗子树 v

肯定是 v 里的点集与已经访问过子树中的点集(红色)进行配对,考虑一对点集产生多少方案。

我们需要考虑 1 选不选,2 选不选,3 选不选。

虽然他们都不是红色子树中的边,但是与 v 中点集配对后都会被经过。

fx,i 表示以 x 为根的子树内选中 i 条边的生成树个数(方案不一定合法)。

注意这里选中的边不一定是生成树内部边,也有可能是生成树的根到 x 之间的边。

现在考虑 v 子树中的一棵生成树。

生成树内部以及生成树的根到 v 之间的边都已经决策过了,只要决策 (x,v) 选还是不选。

fx,i+jfx,i×(fv,j+fv,j1)

其中 f 表示加入 v 后的 f 值。

注意这一部分的答案是要计入最终贡献的,因为统计的都是合法方案。

假设 v 与右边结合的方案已经计算完了。

现在要把一些只在 v 子树的点集加入 f,为下一棵子树的转移做准备。

点集的根到 v 都决策过了,还是考虑选不选 (x,y)

fx,ifv,i+fv,i1

复杂度据说转移时对 k 和子树大小取 min 就能做到 O(nk),很神秘。submission

CF1750G Doping#

题意:疑似有点太难了。

CF1967E1 Again Counting Arrays (Easy Version)#

题意:给定 n,m,b0,求长度为 n 的序列 a 个数,1aim 且存在一个非负序列 b 满足 i[1,n],aibi|bibi1|=1

n,m,b02×105

由于要保证 bi 非负,贪心的使 bi 尽可能大:

  • bi1+1aibi=bi1+1
  • bi1+1=aibi=bi11

如果其中出现 bi 为负,则序列 a 并不存在一个合法的 b

显然每个 a 可以按照这种方式唯一生成一个 b,考虑对 b 计数。

fi,j 表示满足 bi=j 的序列 a 个数。

第一种转移 (m1)fi,jfi+1,j+1。第二种转移 [j<m]fi,jfi+1,j1

如果第 i 个数已经到 m 了,后面随便怎么填都合法,不妨就用 fi,m 记录 jm 的所有情况:mfi,mfi+1,m

时间复杂度 O(nm),不能通过。

从另一个角度考虑这个问题,把 b 的生成看作一个点从 (0,b0) 开始的游走,碰到 y=mx=n 则结束游走。

如果第 i 步往右上走,说明 aim1 种取值;否则 ai 只有一种取值。

枚举 O(n) 种终点 (i,m)(n,j),求从 (0,b0) 不经过 y=1y=m 到达终点的路径数。

终点确定向右上和右下的步数也确定,往右上走对应 m1a 的取值,往右下走对应唯一一种取值。

由于最后一步是确定的,反射容斥的终点设为 (i1,m1) 可以规避一些边界。反射容斥做到单次 O(nm)

取阈值 B=n,按照 m 的大小分两种做法,时间复杂度 O(nB+n2B)submission

P4221 [WC2018] 州区划分#

题意:n 个城市划分为若干州。一个州合法当且仅当其生成子图不存在欧拉回路。求所有合法划分的满意度之和。

一个划分的满意度等于所有州的满意度之积。

i 个州的满意度定义为第 i 个州的人口在前 i 个州的人口中所占比例的 p 次幂,即

(xSiwxj=1ixSjwx)p

给出每个城市的人口 wi 以及常数 p,保证 n21 且无重边无自环。

O(m2n) 预处理每个州 S 是否合法,S 中存在欧拉回路当且仅当子图连通且所有点度数为偶。

W(S)=(xSwx)pf(S) 表示全集为 S 时的答案。

枚举 S 中最后一个州 T

f(S)=TSlegal(T)×f(ST)×W(T)W(S)

W(S) 提出来,记 g(T)=legal(T)×W(T),中间的 f(ST)×g(T) 实际就是一个子集卷积(集合无交并)。

[xSy|S|]g(x,y)=[xS]g(x)x 做或卷积,y 做乘法卷积。

把幂级数看作 n×2n 的矩阵,每次枚举 f 的行 i,和 g 的每行(除第 0 行)做或卷积,把答案累计到 j>if 上(乘法卷积使 y 的指数变大)。

时间复杂度 O(n22n)submission

NFLSOJ 3392. 计算#

题意:定义 F(x,a,b)=gcd(xa1,xb1)+1,如果 a,b 其一为零则值为零。

给出 m,a,b,c,d,令 L=F(m,a,b)+1,R=F(m,c,d),保证 L<R1018,m107

求集合 {L,L+1,,R1,R} 有多少个子集和能被 m 整除。

观察 F 的定义,把他放在 x 进制下考虑,不难发现 F(x,a,b)=xgcd(a,b),举个十进制的例子:gcd(9999,99)=gcd(99999900,99)=10gcd(4,2)1

由于 L1(modm)R0(modm),因此每种余数出现的次数都是 n=RL+1m

枚举子集和:

i=0+[mi][xi]j=0m1(1+xj)n=i=0+1mt=0m1wmti[xi]j=0m1(1+xj)n=1mt=0m1i=0+[xi]j=0m1(1+(wmtx)j)n=1mt=0m1j=0m1(1+wmtj)n

考虑如果 wmti=wmtj 也就是 titj(modm)

那么有 mt(ij),因此指数循环的最小正周期为 m/d,且 0,d,2d,,(m/d1)d 每个恰好出现一次,d=gcd(t,m)

(最小正周期内两两不同余是显然的,tjx(modm) 的必要条件是 dx

因此:

j=0m1(1+wmtj)n=j=0m/d1(1+wm/dj)nd

说明这个乘积与 t 无关,不妨直接枚举 d

1mdmt=1m[tmd]j=0m/d1(1+wm/dj)nd=1mdmφ(md)j=0m/d1(1+wm/dj)nd

根据分圆多项式 xm1=i=0m1(xwmi)

1mdmφ(md)(1)ndj=0m/d1(1wm/dj)nd=1mdmφ(md)(1(1)md)nd=1mdm[2d]φ(d)2nm/d

暴力枚举因子,时间复杂度 O(m+d(m)logn)submission

NFLSOJ 5005. 礼物#

题意:计算有多少个不同的有 n 个珠子的手环,满足有 m 个珠子是金色的,且金色珠子的最长连续段长度不超过 k

两个手环相同当且仅当它们可以通过旋转变得一模一样。1n106,0kmn

一共 n 种旋转置换,第 i 个表示顺时针转 i 格,计算每种置换对应的不动点个数,最后除以 n

考虑一种染色方案的最小正周期 Tn,不妨破环成无限长的链,f(p)=f(p+T)

如果存在 i 使得 f(p)=f(p+i),一定有 Ti,即所有 Tgcd(i,n) 的方案会被 i 计算到。

考虑枚举 d=gcd(i,n) 作为周期,使每种最小正周期 Td 被恰好算一次,有 φ(nd) 种置换满足 d=gcd(i,n)

假设已经特判掉 n=m 的情况,现在可以把环拆成 nd 个完全相同的部分,对这部分计数。

nd,mmdn,破环成链。先把 nm 个白子先排列好,然后插空,满足任意间隔不插超过 k 个,最左最右加起来不超过 k 个。

对于最左最右都不超过 k 的方案很好求,即不定方程 i=1nm+1xi=m, 0xk 的解的数量,可以 O(d) 容斥。

上述方法多算了总和大于 k 的方案数,分两类考虑:左边 k 和左边 >k

考虑第一种情况,我们钦定总和大于 k,并把左右间隔合并,设 z 表示中间钦定大于 k 的间隔。

则这部分的贡献等于 i=1nmxi=m(z+1)(k+1) 的非负整数解个数乘上 k+1,因为把合并间隔拆开,分给左边的有 0,1,,k 种可能。

考虑第二种情况,在钦定左边大于 k 时总和也大于 k,即 i=1nm+1xi=m(z+1)(k+1) 的非负整数解个数。

时间复杂度 dnd=σ(n),即 O(nloglogn)submission

NFLSOJ 12341. 异或#

PKUSC 2023 Day1 狼人杀#

P10221 [省选联考 2024] 重塑时光#

posted @   Lu_xZ  阅读(50)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
menu
点击右上角即可分享
微信分享提示