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

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
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值