There is a beautiful alley with trees in front of a shopping mall. Unfortunately, it has to go to make space for the parking lot.
The trees on the alley all grow in a single line. There are nn spots for trees, index 00 is the shopping mall, index n+1n+1 is the road and indices from 11 to nn are the spots for trees. Some of them are taken — there grow trees of the same height kk. No more than one tree grows in each spot.
When you chop down a tree in the spot xx, you can make it fall either left or right. If it falls to the left, it takes up spots from x−kx−k to xx, inclusive. If it falls to the right, it takes up spots from xx to x+kx+k, inclusive.
Let mm trees on the alley grow in some spots x1,x2,…,xmx1,x2,…,xm. Let an alley be called unfortunate if all mm trees can be chopped down in such a way that:
no tree falls on the shopping mall or the road; each spot is taken up by no more than one fallen tree. Calculate the number of different unfortunate alleys with mm trees of height kk. Two alleys are considered different if there is a spot yy such that a tree grows in yy on the first alley and doesn't grow in yy on the second alley.
Output the number modulo 998244353998244353. 这里有一条美丽的小巷,在一个购物中心的前面有树木。不幸的是,为了给停车场腾出空间,它不得不离开。
巷子里的树都长在一条线上。有n个树点,指数00是商场,指数n+1n+1是道路,指数从11到nn是树点。其中一些位置已经被占用--那里生长着相同高度的树,Kk。每个点都不超过一棵树。
当你在xx点砍下一棵树时,你可以让它向左或向右倒下。如果它向左倒下,它就会占用从x-kx-k到xx的位置,包括在内。如果它向右倒下,它占用的位置从xx到x+kx+k,包括在内。
让小巷上的mm树木在某些位置上生长x1,x2,...,xmx1,x2,...,xm。让我们把一条小巷称为不幸的小巷,如果所有的mm树都能以这样的方式被砍掉,那么:
没有树落在商场或道路上;每个地方被不超过一棵倒下的树占据。计算有mm高的树的不同的不幸的小巷的数量kk。如果有一个点yy,使得第一条小巷的yy里长出了一棵树,而第二条小巷的yy里没有长出一棵树,则认为两条小巷是不同的。
输出数字modulo 998244353998244353。
#include <bits/stdc++.h>
#define int long long
#define endl '\n'
#define lowbit(x) (x&(-x))
#define ull unsigned long long
#define pii pair<int,int>
using namespace std;
const string yes="Yes\n",no="No\n";
const int N = 1000005,inf = 2e18,mod=998244353;
int qpow(int x,int y=mod-2,int mo=mod,int res=1){
for(;y;(x*=x)%=mo,y>>=1)if(y&1)(res*=x)%=mo;
return res;
}
int jie[N],invjie[N];
int C(int n,int m){return n>=m&&m>=0?jie[n]*invjie[m]%mod*invjie[n-m]%mod:0;}
void main_init(){
int n=N-1;jie[0]=1;for(int i=1;i<=n;i++)jie[i]=jie[i-1]*i%mod;
invjie[n]=qpow(jie[n]);for(int i=n-1;~i;i--)invjie[i]=invjie[i+1]*(i+1)%mod;
}
int n,m,k;
void solve(){
cin>>n>>m>>k;
int t=m*(k+1);
if(t>n){
cout<<0;
return;
}
int ans=0;
for(int i=0;i<=m;i++){
(ans+=(i%2?mod-1:1)*qpow(2,m-i)%mod*C(m,i)%mod*C(n-(k+1)*m-k*i+m,m)%mod)%=mod;
}
cout<<ans<<endl;
}
signed main(){
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
cout<<fixed<<setprecision(12);main_init();
int t=1;
//cin>>t;
while (t--)solve();
}