【Atcoder】 [ARC160D] Mahjong

题目链接

Atcoder方向
Luogu方向

题目解法

首先可以考虑将操作逆序
即给定一张全0的数列,有 单点 + K +K +K 与 连续 K K K个数 + 1 +1 +1 的操作,且操作完数列和为 M M M,求方案数
可以发现对于一段 p , p + k − 1 p,p+k-1 p,p+k1,区间 + 1 +1 +1的操作次数一定 < K <K <K
且 单点加的集合、区间加的集合 与 方案 形成双射
证明:

  1. 如果区间 + 1 +1 +1的次数 > = K >=K >=K,那么一定可以转化为单点加 K K K
  2. 考虑一种方案,通过 a 1 a_1 a1 可以知道 1 − K 1-K 1K 区间加的次数(即为 a 1    m o d    K a_1 \;mod\;K a1modK),以此类推,可以依次通过 a 2 , a 3 , . . . a_2,a_3,... a2,a3,... 知道 2 − K , 3 − K , . . . 2-K,3-K,... 2K,3K,... 出现的次数
  3. 显然,一种方案一定可以对应到一个单点加的集合、区间加的集合

对于 K ∤ M K\nmid M KM 的情况,答案为0
对于 K ∣ M K\mid M KM 的情况,即为一个有上限的隔板组合
即有 M K \frac{M}{K} KM 个小球,有 n n n 个位置是没有上限的,有 n − K + 1 n-K+1 nK+1 个位置 < K <K <K,求方案数

对于有限制的组合,一定要想到容斥
容斥至少有 i i i 个超上限
所以 a n s = ∑ i = 0 n − k + 1 ( − 1 ) i ∗ ( i n − k + 1 ) + ( 2 n − k M K − i k + 2 n − k ) ans=\sum_{i=0}^{n-k+1}(-1)^i*(^{n-k+1}_{i})+(^{\frac{M}{K}-ik+2n-k}_{2n-k}) ans=i=0nk+1(1)i(ink+1)+(2nkKMik+2nk)
组合数暴力算一算即可
时间复杂度 O ( n 2 ) O(n^2) O(n2)

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N(4100),P(998244353);
int n,m,k,ans,inv[N];
inline int read(){
	int FF=0,RR=1;
	char ch=getchar();
	for(;!isdigit(ch);ch=getchar()) if(ch=='-') RR=-1;
	for(;isdigit(ch);ch=getchar()) FF=(FF<<1)+(FF<<3)+ch-48;
	return FF*RR;
}
int C(int a,int b){
	int res=1;
	for(int i=0;i<b;i++) res=res*((a-i)%P)%P;
	return res*inv[b]%P;
}
int qmi(int a,int b){
	int res=1;
	for(;b;b>>=1){
		if(b&1) res=res*a%P;
		a=a*a%P; 
	}
	return res;
}
signed main(){
	n=read(),m=read(),k=read();
	if(m%k!=0){ puts("0");exit(0);}
	/*
	2n-k+1组,有i(0<=i<=n-k+1)个不合法
	C(d-i*k+2n-k,2n-k) 
	*/ 
	int d=m/k;
	inv[0]=1;
	for(int i=1;i<=2*n;i++) inv[i]=inv[i-1]*qmi(i,P-2)%P;
	for(int i=0,j=1;i<=n-k+1;i++,j*=-1){
		if(i*k>d) break;
		ans=((ans+j*C(n-k+1,i)*C(d-i*k+2*n-k,2*n-k)%P)%P+P)%P;
	}
	printf("%lld",ans);
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值