【学习笔记】数学知识-组合计数
加法原理(分类计数原理)
- 若完成一件事的方法有 \(n\) 类,其中第 \(i(1 \le i \le n)\) 类方法包括 \(a_i\) 种不同的方法,且这些方法互不重合,则完成这件事共有 \(\sum\limits_{i=1}^{n}a_i\) 种不同的方法。
乘法原理(分步计数原理)
- 若完成一件事的步骤有 \(n\) 个,其中第 \(i(1 \le i \le n)\) 个步骤包括 \(a_i\) 种不同的方法,且这些方法互不重合,则完成这件事共有 \(\prod\limits_{i=1}^{n}a_i\) 种不同的方法。
排列
- 从 \(n\) 个不同元素中依次取出 \(m\) 个不同的元素按照一定的顺序排成一列,产生的不同排列的数量称作排列数,记为 \(A_{n}^{m}\) 或 \(P_{n}^{m}\) 。递推式为 \(A_{n}^{m}=P_{n}^{m}=n(n-1)(n-2) \dots (n-m+1)=\dfrac{n!}{(n-m)!}\) 。
- 相同的排列指元素相同且顺序相同。
- 当 \(m<n\) 时称作选排列;当 \(m=n\) 时称作全排列,由于 \(0!=1\) ,有 \(A_{n}^{n}=n!\) ;当 \(m>n\) 或 \(m<0\) 时,规定 \(A_{n}^{m}=0\) 。
- 通常情况下使用 \(A_{n}^{m}\) 代替 \(P_{n}^{m}\) 。
- 性质
- \(A_{n}^{m}=A_{n}^{m-1} \times (n-m+1)\)
- 应用
- 从 \(n\) 个不同元素可以重复地取出 \(m\) 个不同的元素按照一定的顺序排成一列,考虑顺序,产生的不同排列的数量为 \(n^m\) ,称作相异元素的可重复选排列。
- 从 \(n\) 个不同元素依次取出 \(m\) 个不同的元素按照一定的顺序排成一个环形,考虑顺序,产生的不同环的数量为 \(Q_{n}^{m}=\dfrac{A_{n}^{m}}{m}\) ,称作相异元素的圆排列。
- 相同的环指元素相同且在环上的顺序相同。
- 证明
- 当 \(m=n\) 时,考虑对于其中已经排好的一个环,从不同的位置断开,便可得到不同的排列,即 \(Q_{n}^{n} \times n=A_{n}^{n}=n!\) ,解得 \(Q_{n}^{n}=(n-1)!=\dfrac{A_{n}^{n}}{n}\) 。
- 当 \(m \ne n\) 时,先从 \(n\) 个元素中选出 \(m\) 个元素,再对选出的 \(m\) 个元素进行圆排列,即 \(Q_{n}^{m}=\dbinom{n}{m}Q_{m}^{m}=\dfrac{n!}{m!(n-m)!} \times(m-1)!=\dfrac{n!}{m \times (n-m)!}=\dfrac{A_{n}^{m}}{m}\) 。
- 例题
- CF1433E Two Round Dances
- \(\dfrac{Q_{n}^{\frac{n}{2}}Q_{\frac{n}{2}}^{\frac{n}{2}}}{A_{2}^{2}}\) 即为所求。
- luogu P3330 [ZJOI2011] 看电影
- CF1433E Two Round Dances
- 多重集是指包含重复元素的广义集合。设 \(S= \{ n_{1} \times a_{1},n_{2} \times a_{2}, \dots,n_{k} \times a_{k} \}\) 是由 \(n_{1}\) 个 \(a_{1}\) , \(n_{2}\) 个 \(a_{2}\) \(\dots \ n_{k}\) 个 \(a_{k}\) 组成的多重集。则 \(S\) 的全排列个数为 \(\dfrac{A_{\sum\limits_{i=1}^{k}n_{i}}^{\sum\limits_{i=1}^{k}n_{i}}}{\prod\limits_{i=1}^{k}A_{n_{i}}^{n_{i}}}=\dfrac{(\sum\limits_{i=1}^{k}n_{i})!}{\prod\limits_{i=1}^{k}n_{i}!}\) 。
- 例题
- luogu P5520 [yLOI2019] 青原樱
- luogu P3223 [HNOI2012] 排队
- 老师不相邻方案数 \(=\) 总方案数 \(-\) 老师相邻方案数 \(=A_{n+2}^{n+2}A_{n+3}^{m}-A_{2}^{2}A_{n+1}^{n+1}A_{n+2}^{m}\) 。
- 化简完,得 \(\dfrac{(n+1)!(n+2)!(n^2+3n+2m)}{(n+3-m)!}\) 。
组合
- 从 \(n\) 个不同元素中依次取出 \(m\) 个不同的元素组成一个集合,不考虑顺序,产生的不同集合的数量称作组合数,记为 \(C_{n}^{m}\) 或 \(\dbinom{n}{m}\) ,递推式为 \(C_{n}^{m}=\dbinom{n}{m}=\dfrac{A_{n}^{m}}{A_{m}^{m}}=\dfrac{n!}{m!(n-m)!}\) 。
- 相同的组合指元素相同。
- 当 \(m>n\) 或 \(m<0\) 时,规定 \(\dbinom{n}{m}=0\) 。
- 性质
-
若 \(p \in \mathbb{P}\) ,则对于任意 \(i(1 \le i \le p-1)\) 均满足 \(p|\dbinom{p}{i}\) 。
- 证明:首先由于 \(1 \le i \le p-1\) ,有 \(\dbinom{p}{i}=\dfrac{\prod\limits_{j=p-i+1}^{p}j}{i!}\) 为正整数,又因为 \(\gcd(p,i!)=1\) ,则 \(i!| \prod\limits_{j=p-i+1}^{p-1}j\) ,此时有 \(p|\dbinom{p}{i}\) 。
-
\(\dbinom{n}{m}=\dbinom{n}{n-m}\)
-
\(\dbinom{n}{m}=\dfrac{n}{m} \dbinom{n-1}{m-1}\)
- 证明
- 将式子拆开即可,有 \(\begin{aligned} \dfrac{n}{m} \dbinom{n-1}{m-1} &=\dfrac{(n-1)!n}{(m-1)!(n-m)!m} \\ &=\dfrac{n!}{m!(n-m)!} \\ &=\dbinom{n}{m} \end{aligned}\) 。
- 证明
-
\(\dbinom{n}{m}=\dbinom{n-1}{m}+\dbinom{n-1}{m-1}\)
- 证明
- 将式子拆开即可,有 \(\begin{aligned} \dbinom{n-1}{m}+\dbinom{n-1}{m-1} &=\dfrac{(n-1)!}{m!(n-1-m)!}+\dfrac{(n-1)!}{(m-1)!(n-m)!} \\ &=\dfrac{(n-1)!(n-m)}{m!(n-m)!}+\dfrac{(n-1)!m}{m!(n-m)!} \\ &=\dfrac{n!}{m!(n-m)!} \\ &=\dbinom{n}{m} \end{aligned}\) 。
- 从二项式定理和杨辉三角的角度考虑,此结论是显然的。
- 证明
-
\(\dbinom{n}{k}\dbinom{k}{m}=\dbinom{n}{m}\dbinom{n-m}{k-m}\)
- 证明
- 将式子拆开即可。
- 证明
-
\(\sum\limits_{i=0}^{n}\dbinom{n}{i}=2^{n}\)
- 证明:从二项式定理的角度考虑,取 \(a=b=1\) 的情况即可。
-
\(\sum\limits_{i=0}^{n}(-1)^{i}\dbinom{n}{i}=[n=0]\)
- 证明:从二项式定理的角度考虑,取 \(a=-1,b=1\) 的情况即可。
-
\(\sum\limits_{i=0}^{n}[i \bmod 2=0]\dbinom{n}{i}=\sum\limits_{i=0}^{n}[i \bmod 2=1]\dbinom{n}{i}=2^{n-1}\)
- luogu P3414 SAC#1
- 证明
- 由于 \(\dbinom{n}{i}=\dbinom{n-1}{i}+\dbinom{n-1}{i-1}\) ,故 \(\sum\limits_{i=0}^{n}[i \bmod 2=0]\dbinom{n}{i}=\sum\limits_{i=0}^{n}[i \bmod 2=1]\dbinom{n}{i}=\sum\limits_{i=0}^{n-1}\dbinom{n}{i}=2^{n-1}\) 。
-
\(\sum\limits_{i=0}^{k}\dbinom{n}{i}\dbinom{m}{k-i}=\dbinom{n+m}{k}\)
- 证明
- 从组合意义的角度分析,此结论是显然的。
- 证明
-
\(\sum\limits_{i=0}^{n}\dbinom{n}{i}\dbinom{n}{i}=\dbinom{2n}{n}\)
-
\(\sum\limits_{i=1}^{n}\dbinom{n-i+1}{i}=Fib_{n+2}\)
- 证明详见 2.5 做题纪要 tgHZOJ 264. 选拔队员 。
-
\(\sum\limits_{i=1}^{n}\dbinom{n-i}{i}=Fib_{n+1}\)
- 证明
- 推式子,有 \(\begin{aligned} \sum\limits_{i=1}^{n}\dbinom{n-i}{i} &=\sum\limits_{i=1}^{n-1}\dbinom{n-1-i+1}{i}+\dbinom{n-n}{n} \\ &=Fib_{n+1}+0 \\ &=Fib_{n+1} \end{aligned}\) 。
- 证明
-
- 组合数的求法
-
利用杨辉三角求解,用来解决给定 \(p\) ,多组询问,每次给定较小的 \(n,m\) ,求 \(\dbinom{n}{m} \bmod p\) 。
-
luogu P2822 [NOIP2016 提高组] 组合数问题
点击查看代码
void C(ll n,ll p) { c[0][0]=c[1][0]=c[1][1]=1; for(ll i=2;i<=n;i++) { c[i][0]=1; for(ll j=1;j<=i;j++) { c[i][j]=(c[i-1][j-1]+c[i-1][j])%p; } } }
-
-
现算阶乘和阶乘的逆元,用来解决多组询问,每次给定 \(n,m,p\) ,求 \(\dbinom{n}{m} \bmod p\) ,常搭配 \(Lucas\) 一起使用。
点击查看代码
ll C(ll n,ll m,ll p) { ll a=1,b=1,i; if(n>=m&&n>=0&&m>=0) { for(i=n-m+1;i<=n;i++) { a=a*i%p; } for(i=1;i<=m;i++) { b=b*i%p; } return a*qpow(b,p-2,p)%p; } else { return 0; } }
-
预处理逆元,阶乘,阶乘的逆元,用来解决给定 \(p\) ,多组询问,每次询问给定 \(n,m\) 求 \(\dbinom{n}{m} \bmod p\) 。
-
点击查看代码
ll C(ll n,ll m,ll p) { return (n>=m&&n>=0&&m>=0)?(jc[n]*jc_inv[m]%p)*jc_inv[n-m]%p:0; } inv[1]=1; jc[0]=jc_inv[0]=jc[1]=jc_inv[1]=1; for(i=2;i<=N;i++) { inv[i]=(p-p/i)*inv[p%i]%p; jc[i]=jc[i-1]*i%p; jc_inv[i]=jc_inv[i-1]*inv[i]%p; }
-
-
给定较大数 \(n,m\) ,求 \(\dbinom{n}{m}\) ,且需要高精度时。预处理素数,将分子、分母快速分解质因数,并保存各项质因子的指数,然后将分子、分母各个质因子的指数对应相减,即把分母消去,最后把剩余质因子乘起来。
-
- 应用
- 错位排列
-
错位排列是指没有任何元素出现在其有序位置的排列。即对于 \(1 \sim n\) 的排列 \(P\) ,如果不存在一个 \(i(1 \le i \le n)\) 满足 \(P_i=i\) ,则称 \(P\) 是 \(n\) 的错位排列。记 \(D_{n}\) 表示 \(n\) 个元素的错位排列个数。递推式为 \(D_{n}=\begin{cases}0 & n=1 \\1 & n=2 \\ (n-1)(D_{n-1}+D_{n-2}) & otherwise\end{cases}\) 。特别的,当 \(n \ne 1\) 时,有 \(D_{n}=nD_{n-1}+(-1)^{n}\) 。
- 证明
- 当 \(n=1\) 或 \(n=2\) 时,显然。
- 当 \(n \ne 1\) 且 \(n \ne 2\) 时,首先,设把第 \(n\) 个元素放在第 \(k(k \ne n)\) 个位置,一共有 \(\dbinom{n-1}{1}=n-1\) 种不同的方法。其次,第 \(k\) 个元素放到第 \(n\) 个位置时,一共有 \(D_{n-2}\) 种不同的方法;第 \(k\) 个元素不放到第 \(n\) 个位置时,一共有 \(D_{n-1}\) 种不同的方法。故有 \(D_{n}=(n-1)(D_{n-1}+D_{n-2})\) 。
- 当 \(n \ne 1\) 时,设 \(1 \le k \le n-2\) ,有 \(\begin{aligned} D_{n}-nD_{n-1} &=(n-1)(D_{n-1}+D_{n-2})-nD_{n-1} \\ &=(-1)^{1}(D_{n-1}-(n-1)D_{n-2}) \\ &=(-1)^{2}(D_{n-2}-(n-2)D_{n-3}) \\ &=(-1)^{k}(D_{n-k}-(n-k)D_{n-k-1}) \\ &=(-1)^{n-2}(D_{2}-2D_{1}) \\\ &=(-1)^{n} \end{aligned}\) ,移项得 \(D_{n}=nD_{n-1}+(-1)^{n}\) 。
- 证明
-
代码实现
点击查看代码
d[1]=0; d[2]=1; for(i=3;i<=n;i++) { d[i]=(i-1)*(d[i-1]+d[i-2]); } cout<<d[n]<<endl;
-
例题
- luogu P1595 信封问题
- UVA12024 Hats
- luogu P3182 [HAOI2016]放棋子
-
将障碍转化成错排挺显然的。 \(D_{n}\) 即为所求。
点击查看代码
ll d[201][200],len[201],ans[200]; void jia(ll c[],ll &lenc,ll a[],ll &lena,ll b[],ll &lenb) { ll i,x=0; lenc=max(lena,lenb); for(i=1;i<=lenc;i++) { c[i]=a[i]+b[i]+x; if(c[i]>=1000000000000000) { x=c[i]/1000000000000000; c[i]%=1000000000000000; } else { x=0; } } lenc++; c[lenc]=x; while(lenc>0&&c[lenc]==0) { lenc--; } } void cheng(ll a[],ll &lena,ll b) { ll i,x=0; for(i=1;i<=lena;i++) { ans[i]=a[i]*b+x; if(ans[i]>=1000000000000000) { x=ans[i]/1000000000000000; ans[i]%=1000000000000000; } else { x=0; } } lena++; ans[lena]=x; while(lena>0&&ans[lena]==0) { lena--; } if(lena==0) { lena++; ans[lena]=1; } for(i=1;i<=lena;i++) { a[i]=ans[i]; } } int main() { ll n,i; cin>>n; len[1]=len[2]=1; d[1][1]=0; d[2][1]=1; for(i=3;i<=n;i++) { jia(d[i],len[i],d[i-1],len[i-1],d[i-2],len[i-2]); cheng(d[i],len[i],i-1); } cout<<d[n][len[n]]; for(i=len[n]-1;i>=1;i--) { printf("%015lld",d[n][i]); } return 0; }
-
- luogu P4071 [SDOI2016] 排列计数
-
\(\dbinom{m}{n}D_{n-m}\) 即为所求。
- 特别地,本题要求 \(D_{0}=1\) 。
点击查看代码
ll inv[1000001],jc[1000001],jc_inv[1000001],d[1000001]; ll C(ll n,ll m,ll p) { return (n>=m&&n>=0&&m>=0)?((jc[n]*jc_inv[m]%p)*jc_inv[n-m]%p):0; } int main() { ll t,n,m,p=1000000007,i; scanf("%lld",&t); inv[1]=1; jc[0]=jc_inv[0]=jc[1]=jc_inv[1]=1; d[0]=1; d[1]=0; d[2]=1; for(i=3;i<=1000000;i++) { d[i]=((i-1)%p)*((d[i-1]+d[i-2])%p)%p; } for(i=2;i<=1000000;i++) { inv[i]=(p-p/i)*inv[p%i]%p; jc[i]=jc[i-1]*i%p; jc_inv[i]=jc_inv[i-1]*inv[i]%p; } for(i=1;i<=t;i++) { scanf("%lld%lld",&n,&m); printf("%lld\n",C(n,m,p)*d[n-m]%p); } return 0; }
-
- CF340E Iahub and Permutations
-
- 设 \(S= \{ n_{1} \times a_{1},n_{2} \times a_{2}, \dots,n_{k} \times a_{k} \}\) 是由 \(n_{1}\) 个 \(a_{1}\) , \(n_{2}\) 个 \(a_{2}\) \(\dots \ n_{k}\) 个 \(a_{k}\) 组成的多重集。设整数 \(m \le \min\limits_{i=1}^{k} \{ n_{i} \}\) ,则从 \(S\) 中选出 \(m\) 个元素组成一个多重集(不考虑元素顺序),产生的不同多重集的数量为 \(\dbinom{k+m-1}{k-1}\) 。
- 卡特兰数
- 错位排列
- 例题
- SP28304 ADATEAMS - Ada and Teams
- luogu P1771 方程的解
-
\(\sum\limits_{i=1}^{n}x_i=m\) 的正整数解的数量为 \(\dbinom{m-1}{n-1}\) 。
- 等价于求把 \(m\) 个不同的小球分成 \(n\) 个部分,使得每个部分至少有一个小球的方案数。
-
\(\sum\limits_{i=1}^{n}x_i=m\) 的非负整数解的数量为 \(\dbinom{n+m-1}{n-1}\) 。
- 等价于求 \(\sum\limits_{i=1}^{n}x_i=n+m\) 的正整数解的数量。
点击查看代码
ll num[1001],a[1001],ans[1001],lena=1; void cheng(ll a[],ll &lena,ll b) { ll i,x=0; for(i=1;i<=lena;i++) { ans[i]=a[i]*b+x; if(ans[i]>=1000000000000000) { x=ans[i]/1000000000000000; ans[i]%=1000000000000000; } else { x=0; } } lena++; ans[lena]=x; while(lena>0&&ans[lena]==0) { lena--; } if(lena==0) { lena++; ans[lena]=1; } for(i=1;i<=lena;i++) { a[i]=ans[i]; } } void divide(ll n,ll pd) { ll i,sum=0; for(i=2;i<=sqrt(n);i++) { if(n%i==0) { sum=0; while(n%i==0) { n/=i; sum++; } num[i]+=pd*sum; } } if(n>1) { num[n]+=pd; } } ll qpow(ll a,ll b,ll p) { ll ans=1; while(b>0) { if(b&1) { ans=ans*a%p; } b>>=1; a=a*a%p; } return ans; } void C(ll n,ll m) { ll i,j; if(n>=m) { for(i=n-m+1;i<=n;i++) { divide(i,1); } for(i=1;i<=m;i++) { divide(i,-1); } for(i=1;i<=n;i++) { if(num[i]!=0) { for(j=1;j<=num[i];j++) { cheng(a,lena,i); } } } } } int main() { ll k,x,p=1000,i; cin>>k>>x; a[1]=1; C(qpow(x,x,p)-1,k-1); cout<<a[lena]; for(i=lena-1;i>=1;i--) { printf("%015lld",a[i]); } return 0; }
-
- luogu P1350 车的放置
- 将棋盘分割为 \(a \times (b+d)\) 和 \(c \times d\) 的矩阵,因为 \(a \times (b+d)\) 和 \(c \times d\) 的矩阵放置的车有冲突情况,故 \(\sum\limits_{i=0}^{n}\dbinom{a}{i}\dbinom{b+d-(k-i)}{i}A_{i}^{i}\dbinom{c}{k-i}\dbinom{d}{k-i}A_{k-i}^{k-i}\) 即为所求。
- luogu P2606 [ZJOI2010] 排列计数
-
对于常见的计数 \(DP\) ,记录是从哪个元素转移来的会耗费大量的空间,且无法确定是否合法。因此就需要利用离散化的思想来实现“等效代换”,记录其相对的大小关系。
-
容易发现满足性质的序列是一个小根堆。
-
设 \(s_i\) 表示以 \(i\) 为根的小根堆的大小, \(f_i\) 表示以 \(i\) 为根的小根堆的合法方案数。
-
因为要求自己是最小的,故需要在 \(s_i-1\) 个中选出 \(s_{2i}\) 个给左儿子,剩下的 \(s_{2i+1}\) 个给有右儿子。
-
故得到转移方程 \(s_i=s_{2i}+s_{2i+1}+1,f_i=\dbinom{s_{2i}}{s_i-1}f_{2i}f_{2i+1}\) 。最后, \(f_1\) 即为所求。
- 此时该小根堆内记录的不是实际元素,而是其之间的大小关系。
- 这里如果不理解,可以自己带几组样例模拟一下。
点击查看代码
ll inv[3000001],jc[3000001],jc_inv[3000001],f[3000001],s[3000001]; ll C(ll n,ll m,ll p) { if(n>=m&&n>=0&&m>=0) { return (jc[n]*jc_inv[m]%p)*jc_inv[n-m]%p; } else { return 0; } } ll lucas(ll n,ll m,ll p) { return m?C(n%p,m%p,p)*lucas(n/p,m/p,p)%p:1; } int main() { ll n,p,i; cin>>n>>p; inv[1]=1; jc[0]=jc_inv[0]=jc[1]=jc_inv[1]=1; for(i=2;i<=min(n,p-1);i++) { inv[i]=(p-p/i)*inv[p%i]%p; jc[i]=jc[i-1]*i%p; jc_inv[i]=jc_inv[i-1]*inv[i]%p; } for(i=1;i<=2*n+1;i++) { f[i]=1; } for(i=n;i>=1;i--) { s[i]=s[i*2]+s[i*2+1]+1; f[i]=(lucas(s[i]-1,s[i*2],p)*f[i*2]%p)*f[i*2+1]%p; } cout<<f[1]<<endl; return 0; }
- 此时该小根堆内记录的不是实际元素,而是其之间的大小关系。
-
- luogu P6191 [USACO09FEB] Bulls And Cows S | HZOJ 720.种树
- 详见 普及模拟3 T4 种树 。
- LibreOJ 10235. 「一本通 6.6 练习 6」序列统计
-
记 \(m=r-l+1\) ,设 \(0 \le k \le n-1\) ,枚举长度 \(i\) ,等价于求 \(\sum\limits_{j=1}^{m}x_j=i\) 的非负整数解的数量。
-
推式子,有 \(\begin{aligned} \sum\limits_{i=1}^{n}\dbinom{m+i-1}{i} &=\dbinom{m}{0}-1+\sum\limits_{i=1}^{n}\dbinom{m+i-1}{i} \\ &=\dbinom{m}{1}+\dbinom{m}{0}-1+\sum\limits_{i=2}^{n}\dbinom{m+i-1}{i} \\ &=\dbinom{m+1}{1}-1+\sum\limits_{i=2}^{n}\dbinom{m+i-1}{i} \\ &=\dbinom{m+k}{k}-1+\sum\limits_{i=k+1}^{n}\dbinom{m+i-1}{i} \\ &=\dbinom{m+n-1}{n-1}+\dbinom{m+n-1}{n}-1 \\ &=\dbinom{n+m}{n}-1 \end{aligned}\) 。
点击查看代码
ll inv[1000010],jc[1000010],jc_inv[1000010]; ll C(ll n,ll m,ll p) { if(n>=m&&n>=0&&m>=0) { return (jc[n]*jc_inv[m]%p)*jc_inv[n-m]%p; } else { return 0; } } ll lucas(ll n,ll m,ll p) { return m?C(n%p,m%p,p)*lucas(n/p,m/p,p)%p:1; } int main() { ll t,n,m,l,r,i,p=1000003; cin>>t; inv[1]=1; jc[0]=jc_inv[0]=jc[1]=jc_inv[1]=1; for(i=2;i<=p-1;i++) { inv[i]=(p-p/i)*inv[p%i]%p; jc[i]=jc[i-1]*i%p; jc_inv[i]=jc_inv[i-1]*inv[i]%p; } for(i=1;i<=t;i++) { cin>>n>>l>>r; m=r-l+1; cout<<(lucas(n+m,n,p)+p-1)%p<<endl; } return 0; }
-
- BZOJ3462 DZY Loves Math II
- luogu P2154 [SDOI2009] 虔诚的墓主人
-
观察到 \(n,m\) 极大,但 \(w\) 较小,于是考虑进行离散化。
-
对于横坐标相等, \(y_{i} \le y_{j}\) 的两棵常青树 \(i,j\) ,其相隔的 \(y_{j}-y_{i}\) 个墓地对答案产生的贡献为 \(\dbinom{up_{x_{i}}}{k}\dbinom{down_{x_{i}}}{k}\sum\limits_{h=y_{i}+1}^{y_{j}-1}\dbinom{lift_{h}}{k}\dbinom{right_{h}}{k}\) ,其中 \(up_{l},down_{l},left_{l},right{l}\) 分别表示 \((x,l)\) 上、下、左、右方常青树的个数。
-
\(\dbinom{up_{x_{i}}}{k}\dbinom{down_{x_{i}}}{k}\) 在枚举常青树的过程中即可处理。
-
考虑用单点修改、区间查询的树状数组维护 \(\sum\limits_{h=y_{i}+1}^{y_{j}-1}\dbinom{lift_{h}}{k}\dbinom{right_{h}}{k}\) 。注意枚举到一棵新的常青树时,要先减去其原来对答案的贡献,重新计算贡献。
-
细节较多。
点击查看代码
struct node { ll x,y; }a[100010]; ll x[100010],y[100010],c[100010][11],c2[100010][2],l[100010],sum[100010][2]; bool cmp(node a,node b) { return (a.x==b.x)?(a.y<b.y):(a.x<b.x); } ll query(ll a[],ll x) { return lower_bound(a+1,a+1+a[0],x)-a; } ll lowbit(ll x) { return (x&(-x)); } void add(ll n,ll x,ll key,ll p) { ll i; for(i=x;i<=n;i+=lowbit(i)) { c2[i][0]=(c2[i][0]+key+p)%p; } } ll getsum(ll x,ll p) { ll ans=0,i; for(i=x;i>0;i-=lowbit(i)) { ans=(ans+c2[i][0])%p; } return ans; } void C(ll n,ll m,ll p) { c[0][0]=c[1][0]=c[1][1]=1; for(ll i=2;i<=n;i++) { c[i][0]=1; for(ll j=1;j<=m;j++) { c[i][j]=(c[i-1][j-1]+c[i-1][j])%p; } } } int main() { ll n,m,w,k,u,d=0,r,lr,i,ans=0,p=2147483648; cin>>n>>m>>w; a[0].x=a[0].y=0; for(i=1;i<=w;i++) { cin>>a[i].x>>a[i].y; a[i].x++; a[i].y++; x[i]=a[i].x; y[i]=a[i].y; } cin>>k; sort(x+1,x+1+w); sort(y+1,y+1+w); x[0]=unique(x+1,x+1+w)-(x+1); y[0]=unique(y+1,y+1+w)-(y+1); C(w,k,p); for(i=1;i<=w;i++) { a[i].x=query(x,a[i].x); a[i].y=query(y,a[i].y); sum[a[i].x][0]++; sum[a[i].y][1]++; } sort(a+1,a+1+w,cmp); for(i=1;i<=w-1;i++) { d=((a[i-1].x==a[i].x)?d:0)+1; u=sum[a[i].x][0]-d; if(d>=k&&u>=k&&a[i].x==a[i+1].x) { lr=(a[i+1].y-1>=a[i].y+1)?(getsum(a[i+1].y-1,p)-getsum(a[i].y+1-1,p)+p)%p:0; ans=(ans+(((c[d][k]*c[u][k])%p)*lr)%p)%p; } add(y[0],a[i].y,-c2[a[i].y][1],p); l[a[i].y]++; r=sum[a[i].y][1]-l[a[i].y]; c2[a[i].y][1]=(l[a[i].y]>=k&&r>=k)?(c[l[a[i].y]][k]*c[r][k])%p:0; add(y[0],a[i].y,c2[a[i].y][1],p); } cout<<ans<<endl; return 0; }
-
- luogu P2467 [SDOI2010] 地精部落
-
设 \(f_i\) 表示长度为 \(i\) 的山脉且第一个位置是山谷的合法方案数, \(g_i\) 表示长度为 \(i\) 的山脉且第一个位置是山峰的合法方案数。
- 此时该山脉内记录的不是实际元素,而是其之间的大小关系。
-
容易有 \(f_i\) 从 \(f_{i-1}\) 转移过来的过程中,将 \(i\) 加入其中,一定是放在山峰的位置,故枚举插入的位置 \(j(j \bmod 2=0)\) ,从 \(i-1\) 个里面选出 \(j-1\) 个放在插入的 \(i\) 的左边,剩下的 \((i-1)-(j-1)\) 个放在插入的 \(i\) 的右边。 \(g_i\) 同理。
-
故得到转移方程 \(\begin{cases}f_i=\sum\limits_{j=1}^{i}[j \bmod 2=0] \dbinom{i-1}{j-1}f_{j-1}f_{(i-1)-(j-1)} \\ g_i=\sum\limits_{j=1}^{i}[j \bmod 2=1] \dbinom{i-1}{j-1}g_{j-1}f_{(i-1)-(j-1)} \end{cases}\) 。最终,有 \(f_n+g_n\) 即为所求。
点击查看代码
ll c[2][4400],f[4400],g[4400]; int main() { ll n,p,i,j; cin>>n>>p; c[0][0]=c[1][0]=c[1][1]=1; f[0]=g[0]=f[1]=g[1]=1; for(i=2;i<=n;i++) { for(j=1;j<=i;j++) { c[i%2][0]=1; if(j%2==0) { f[i]=(f[i]+(((c[(i-1)%2][j-1]*f[j-1])%p)*f[(i-1)-(j-1)])%p)%p; } else { g[i]=(g[i]+(((c[(i-1)%2][j-1]*g[j-1])%p)*f[(i-1)-(j-1)])%p)%p; } c[i%2][j]=(c[(i-1)%2][j-1]+c[(i-1)%2][j])%p; } } cout<<(f[n]+g[n])%p<<endl; return 0; }
-
- luogu P4910 帕秋莉的手环
- luogu P3214 [HNOI2011] 卡农
二项式定理、二项式反演
- 二项式定理
- 二项式定理: \((a+b)^n=\sum\limits_{i=0}^{n}\dbinom{n}{i}a^{i}b^{n-i}\) 。
- 证明
- 数学归纳法
- 当 \(n=1\) 时, \((a+b)^1=\dbinom{1}{0}a^0b^1+\dbinom{1}{1}a^1b^0=a+b\) 成立。
- 假设当 \(n=m\) 时命题成立,当 \(n=m+1\) 时,有 \(\begin{aligned} (a+b)^{m+1} &=(a+b)(a+b)^m \\ &=(a+b)\sum\limits_{i=0}^{m}\dbinom{m}{i}a^{i}b^{m-i} \\ &=\sum\limits_{i=0}^{m}\dbinom{m}{i}a^{i+1}b^{m-i}+\sum\limits_{i=0}^{m}\dbinom{m}{i}a^{i}b^{m-i+1} \\ &=\sum\limits_{i=1}^{m+1}\dbinom{m}{i-1}a^{i}b^{m-i+1}+\sum\limits_{i=0}^{m}\dbinom{m}{i}a^{i}b^{m-i+1} \\ &=\dbinom{m}{m}a^{m+1}b^{0}+\dbinom{0}{m}a^{0}b^{m+1}+\sum\limits_{i=1}^{m}(\dbinom{m}{i-1}+\dbinom{m}{i})a^{i}b^{m+1-i} \\ &=\dbinom{m+1}{m+1}a^{m+1}b^{0}+\dbinom{0}{m+1}a^{0}b^{m+1}+\sum\limits_{i=1}^{m}\dbinom{m+1}{i}a^{i}b^{m+1-i} \\ &=\sum\limits_{i=0}^{m+1}\dbinom{m+1}{i}a^{i}b^{m+1-i} \end{aligned}\) 。
- 证毕。
- 组合意义
- 将 \((a+b)^n\) 展开时可以理解为从 \(n\) 个式子 \(a+b\) 中的 \(i(0 \le i \le n)\) 个里取 \(a\) ,剩下的 \(n-i\) 个式子 \(a+b\) 里取 \(b\) ,组成一个乘积项 \(a^{i}b^{n-i}\) ,其系数为 \(\dbinom{n}{i}\) 。
- 数学归纳法
- 例题
- 二项式反演
- 设 \(f_{n}\) 表示恰好 \(n\) 个元素组成特定结构的方案数, \(g_{n}\) 表示从 \(n\) 个元素中选出 \(i(i \ge 0)\) 个元素组成特定结构(虽然其他元素可能一并组成特定结构,但我们不去管它)的总方案数,即 \(g_{n}=\sum\limits_{i=0}^{n}\dbinom{n}{i}f_{i}\) ,那么有 \(f_{n}=\sum\limits_{i=0}^{n}(-1)^{n-i}\dbinom{n}{i}g_{i}\) 。
- 证明
- 推式子,有 \(\begin{aligned} f_{n} &=\sum\limits_{i=0}^{n}(-1)^{n-i}\dbinom{n}{i}g_{i} \\ &=\sum\limits_{i=0}^{n}(-1)^{n-i}\dbinom{n}{i}(\sum\limits_{j=0}^{i}\dbinom{i}{j}f_{j}) \\ &=\sum\limits_{i=0}^{n}\sum\limits_{j=0}^{i}\dbinom{n}{i}\dbinom{i}{j}(-1)^{n-i}f_{j} \\ &=\sum\limits_{j=0}^{n}\sum\limits_{i=j}^{n}\dbinom{n}{i}\dbinom{i}{j}(-1)^{n-i}f_{j} \\ &=\sum\limits_{j=0}^{n}f_{j}(\sum\limits_{i=j}^{n}\dbinom{n}{i}\dbinom{i}{j}(-1)^{n-i}) \\ &=\sum\limits_{j=0}^{n}f_{j}(\sum\limits_{i=j}^{n}\dbinom{n}{j}\dbinom{n-j}{j}(-1)^{n-i}) \\ &=\sum\limits_{j=0}^{n}\dbinom{n}{j}f_{j}(\sum\limits_{i=j}^{n}\dbinom{n-j}{j}(-1)^{n-i}) \\ &=\sum\limits_{j=0}^{n}\dbinom{n}{j}f_{j}(\sum\limits_{k=0}^{n-j}\dbinom{n-j}{k}(-1)^{n-(j+k)}) \\ &=\sum\limits_{j=0}^{n}\dbinom{n}{j}f_{j}(\sum\limits_{k=0}^{n-j}\dbinom{n-j}{k}(-1)^{n-j-k}) \\ &=\sum\limits_{j=0}^{n}\dbinom{n}{j}f_{j}[n-j=0] \\ &=\sum\limits_{j=0}^{n}\dbinom{n}{j}f_{j}[n=j] \\ &=f_{n} \end{aligned}\)
- 其他形式
- 设 \(f_{i}\) 表示 \(n\) 个元素中恰好有 \(i\) 个元素满足特定条件的方案数, \(g_{i}\) 表示 \(n\) 个元素中至少有 \(i\) 个元素满足特定条件的方案数,即 \(g_{m}=\sum\limits_{i=m}^{n}\dbinom{i}{m}f_{i}\) ,那么有 \(f_{m}=\sum\limits_{i=m}^{n}(-1)^{i-m}\dbinom{i}{m}g_{i}\) 。
- 例题
卢卡斯定理
-
卢卡斯定理:若 \(p\) 是质数,则对于任意正整数 \(n,m\) ,有 \(n=(n_kn_{k-1} \dots n_1)_p,m=(m_km_{k-1} \dots m_1)_p\) ,其中对于每一个 \(i(1 \le i \le k)\) 均满足 \(0 \le n_i,m_i \le p-1\),则 \(\dbinom{n}{m} \equiv \prod\limits_{i=1}^{k}\dbinom{n_i}{m_i}\pmod{p}\) 。
- 另一种写法为 \(\dbinom{n}{m} \equiv \dbinom{n \bmod p}{m \bmod p}\dbinom{\left\lfloor \frac{n}{p} \right\rfloor}{\left\lfloor \frac{m}{p} \right\rfloor} \pmod{p}\) .
-
证明
- 考虑对于多项式 \((1+x)^n\) ,展开后 \(x^m\) 的系数为 \(\dbinom{n}{m}\) 。
- 此时有 \(\begin{aligned} (1+x)^n &=\prod\limits_{i=1}^{k}(1+x)^{p^{i-1} \times n_i} \pmod{p} \\ &=\prod\limits_{i=1}^{k}((1+x)^{p^{i-1}})^{n_i} \pmod{p} \\ &=\prod\limits_{i=1}^{k}(\sum\limits_{j=0}^{p^{i-1}}\dbinom{n}{j}x^{j})^{n_i} \pmod{p} \\ & \equiv \prod\limits_{i=1}^{k}(1+x^{p^{i-1}})^{n_i} \pmod{p} \\ &= \prod\limits_{i=1}^{k}\sum\limits_{j=0}^{n_i}\dbinom{n_i}{j}x^{p^{i-1}j} \pmod{p} \end{aligned}\) 。
- 据 \(p\) 进制数的性质,将同余右边展开后有 \(x^m\) 的系数为 \(\prod\limits_{i=1}^{k}\dbinom{n_i}{m_i}\) 。
- 证毕。
-
性质
- \(\dbinom{n}{m}\) 为奇数当且仅当在二进制表示下 \(n\) 的每一个数位的数都不小于 \(m\) 的相应数位的数,即 \(n \And m=m\) 。
-
代码实现
点击查看代码
ll lucas(ll n,ll m,ll p) { return (n>=m&&n>=0&&m>=0)?(m?C(n%p,m%p,p)*lucas(n/p,m/p,p)%p:1):0; }
-
例题
扩展卢卡斯定理
容斥原理
- 容斥原理:设 \(S= \{ S_{1},S_{2},S_{3}, \dots ,S_{n} \}\) ,则有 \(|\bigcup\limits_{i=1}^{n}S_{i}|=\sum\limits_{T \subseteq S}(-1)^{|T|+1} \times |\bigcap\limits_{i=1}^{|T|}T_{i}|\) 。
- 应用
- 设 \(S= \{ n_{1} \times a_{1},n_{2} \times a_{2}, \dots,n_{k} \times a_{k} \}\) 是由 \(n_{1}\) 个 \(a_{1}\) , \(n_{2}\) 个 \(a_{2}\) \(\dots \ n_{k}\) 个 \(a_{k}\) 组成的多重集。设整数 \(m \le \sum\limits_{i=1}^{k}n_{i}\) ,则从 \(S\) 中选出 \(m\) 个元素组成一个多重集(不考虑元素顺序),产生的不同多重集的数量为 \(\dbinom{k+m-1}{k-1}-\sum\limits_{T \subseteq \{ n_{1},n_{2}, \dots,n_{k} \},|T| \ge 1}(-1)^{|T|+1} \times \dbinom{k+m-1-\sum\limits_{i=1}^{|T|}(T_{i}+1)}{k-1}\) ,合并得 \(\sum\limits_{T \subseteq \{ n_{1},n_{2}, \dots,n_{k} \}}(-1)^{|T|} \times \dbinom{k+m-1-\sum\limits_{i=1}^{|T|}(T_{i}+1)}{k-1}\) 。
- 证明
- 等价于求 \(\sum\limits_{i=1}^{k}x_{i}=m(x_{i} \le n_{i})\) 的不同方案数。
- 正难则反,考虑合法方案数等于总方案数减不合法方案数。
- 总方案数同 luogu P1771 方程的解 ,即 \(\dbinom{k+m-1}{k-1}\) 。
- 难点在于如何求不合法方案数。设 \(S_{i}(1 \le i \le k)\) 表示至少包含 \(n_{i}+1\) 个 \(a_{i}\) 的多重集,则 \(S_{i}\) 的方案数为 \(\dbinom{k+m-1-(n_{i}+1)}{k-1}\) 。接着容斥原理,得出 \(|\bigcup\limits_{i=1}^{k}S_{i}|=\sum\limits_{T \subseteq \{ n_{1},n_{2}, \dots,n_{k} \},|T| \ge 1}(-1)^{|T|+1} \times |\bigcap\limits_{i=1}^{|T|}T_{i}|\) ,其方案数为 \(\sum\limits_{T \subseteq \{ n_{1},n_{2}, \dots,n_{k} \},|T| \ge 1}(-1)^{|T|+1} \times \dbinom{k+m-1-\sum\limits_{i=1}^{|T|}(T_{i}+1)}{k-1}\) 。
- 二者相减即可得到原式。
- 证明
- 设 \(S= \{ n_{1} \times a_{1},n_{2} \times a_{2}, \dots,n_{k} \times a_{k} \}\) 是由 \(n_{1}\) 个 \(a_{1}\) , \(n_{2}\) 个 \(a_{2}\) \(\dots \ n_{k}\) 个 \(a_{k}\) 组成的多重集。设整数 \(m \le \sum\limits_{i=1}^{k}n_{i}\) ,则从 \(S\) 中选出 \(m\) 个元素组成一个多重集(不考虑元素顺序),产生的不同多重集的数量为 \(\dbinom{k+m-1}{k-1}-\sum\limits_{T \subseteq \{ n_{1},n_{2}, \dots,n_{k} \},|T| \ge 1}(-1)^{|T|+1} \times \dbinom{k+m-1-\sum\limits_{i=1}^{|T|}(T_{i}+1)}{k-1}\) ,合并得 \(\sum\limits_{T \subseteq \{ n_{1},n_{2}, \dots,n_{k} \}}(-1)^{|T|} \times \dbinom{k+m-1-\sum\limits_{i=1}^{|T|}(T_{i}+1)}{k-1}\) 。
- 例题
本文来自博客园,作者:hzoi_Shadow,原文链接:https://www.cnblogs.com/The-Shadow-Dragon/p/17824983.html,未经允许严禁转载。
版权声明:本作品采用 「署名-非商业性使用-相同方式共享 4.0 国际」许可协议(CC BY-NC-SA 4.0) 进行许可。