题目链接:https://ac.nowcoder.com/acm/contest/887/I
题意:给定n,m。求k*k的矩阵,1<=k<=n,矩阵内的每个元素都不小于m,且矩阵内不同行不同列的元素相加都为一个定值T,且T<=n。问这样的矩阵有多少种,MOD998244353
官方题解:
容易证明,一个k*k棋盘的排布方案满足“不同行不同列的方格内的玻璃球数量的总和均相同”要求,当且仅当该方案具有如下形式
,其中
为第i行(列)均为1,其余行(列)均为0的k*k矩阵,又因为该和为T,所以
和
嘘满足以下关系:
容易得到,满足该条件的方案数为:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=3e4+5;
const ll MOD=998244353;
ll f[maxn], n_f[maxn];
ll pow_(ll x, ll y){
ll ret = 1;
while(y){
if (y & 1)
ret=ret * x % MOD;
x = x * x % MOD;
y >>= 1;
}
return ret;
}
void init(){
f[0] = n_f[0] = 1;
for (ll i = 1; i < maxn; i++)
f[i] = f[i - 1] * i % MOD;
n_f[maxn - 1] = pow_(f[maxn - 1], MOD-2);
for (ll i = maxn - 1; i ; i--)
n_f[i - 1] = n_f[i] * i % MOD;
}
ll C(ll x, ll y){
return f[x] * n_f[y] % MOD * n_f[x - y] % MOD;
}
int main(){
init();
int T;
scanf("%d", &T);
while(T--){
ll n,m;
scanf("%lld%lld",&n,&m);
ll ans=0;
for(ll k = 1; k * m <= n; k++){
ll tt = n - k * m;
for(ll t = 0; t <= tt; t++){
ans = (ans + C(t + 2 * k - 1, 2 * k - 1)) % MOD;
if(t >= k) ans = (ans - C(t + k - 1, 2 * k - 1) + MOD) % MOD;
}
}
printf("%lld\n", ans);
}
return 0;
}