组合数

题目链接:https://www.luogu.com.cn/problem/P2822

题意:

对于0<=i<=n , 0<=j<=min(i,m)的组合数
求其中有多少个k的倍数

思路:

组合数递推公式:f[i][j]=f[i-1]j-1
由于后面的组合数非常大,所以需要取模k

利用二维前缀和,计算nxmin(n,m)的面积中有多少个0即可

int f[maxn+2][maxn+2];
int pre[maxn+2][maxn+2];
void solve(){
	int t,k;cin>>t>>k;
	for(int i=0;i<=maxn;i++)for(int j=0;j<=maxn;j++)f[i][j]=-1;
	for(int i=0;i<=maxn;i++){
		for(int j=0;j<=i;j++){
			if(j==0||j==i){
				f[i][j]=1;
			}
			else f[i][j]=(f[i-1][j]+f[i-1][j-1])%k;
		}
	}
	for(int i=1;i<=maxn;i++){
		for(int j=1;j<=maxn;j++){
			int sum=0;
			if(pre[i-1][j]>0)sum+=pre[i-1][j];
			if(pre[i][j-1]>0)sum+=pre[i][j-1];
			if(pre[i-1][j-1]>0)sum-=pre[i-1][j-1];
			if(f[i][j]==0)sum++;
			pre[i][j]=sum;
		}
	}
	
	for(int i=1;i<=t;i++){
		int n,m;cin>>n>>m;
		cout<<pre[n][min(n,m)]<<endl;
	} 

}
posted @ 2025-04-09 10:39  Marinaco  阅读(36)  评论(0)    收藏  举报
//雪花飘落效果