[组合数学][六省联考2017]组合数问题

it2023-07-25  72

T3

Portkey

1.1 1 ≤ n , k ≤ 30 1\le n,k\le 30 1n,k30

递推算组合数 (似乎这种方法还能再A一个点)

差评zgs的机子 不给这点分

1.2 特殊点

p = 2 p=2 p=2判断奇偶性 k = 1 k=1 k=1二项式定理 k = 2 k=2 k=2跟二项式定理差不多

1.3

用一些稍微高级的方法 预处理啊,阶乘逆元啊之类的 不要暴力就行了

1.4

冯巨来也!

来一个生成函数 ( n m ) = ( 1 + z ) n [ z m ] \binom{n}{m}=(1+z)^n[z^m] (mn)=(1+z)n[zm] 这道题里: ∑ i = 0 ∞ C n k i k + r = ∑ i = 0 ∞ ( 1 + z ) n k [ z i k + r ] \sum_{i=0}^\infin C_{nk}^{ik+r}=\sum_{i=0}^\infin(1+z)^{nk}[z^{ik+r}] i=0Cnkik+r=i=0(1+z)nk[zik+r] 右边是个卷积 然后有一个循环卷积的高级东西

只是下标模了 T T T

其实不需要什么高级的方法 因为这里 k k k很小,直接暴力乘就行

1.5

还有更多的高级方法

矩阵快速幂 DP来推柿子 等等

1.6 Code

代码第27~31行 k = 1 k=1 k=1就是二项式定理,所有系数和为 2 k 2^k 2k k ≠ 1 k\not=1 k=1是二项式展开,就是杨辉三角

#include<bits/stdc++.h> using namespace std; #define in Read() int in{ int i=0;bool f=true;char ch=0; while(!isdigit(ch)&&ch!='-') ch=getchar(); if(ch=='-') ch=getchar(),f^=1; while(isdigit(ch)) i=(i<<1)+(i<<3)+ch-48,ch=getchar(); return f?i:-i; } typedef long long ll; typedef vector<ll> poly; int n,p,k,r; poly operator * (const poly &a,const poly &b){ poly c(k); for(int i=0;i<a.size();++i) for(int j=0;j<b.size();++j) (c[(i+j)%k]+=a[i]*b[j])%=p; return c; } int main(){ n=in,p=in,k=in,r=in; poly a(k),ans(k); if(k==1){ a[0]=2%p; }else{ a[0]=a[1]=1; } ans[0]=1; ll e=1ll*n*k; while(e){ if(e&1) ans=ans*a; a=a*a; e>>=1; } cout<<ans[r]; return 0; }
最新回复(0)