[AT_abc431_f] [ABC431F] Almost Sorted 2 题解
aeiouaoeiu · · 题解
条件就是在说,前一项最多比后一项大
考虑从大到小地填数。设当前填到数值
下面分析插入的方案数怎么计算。第一个被插入的
最终答案如下。
计算组合数,设
::::info[code]
#include<bits/stdc++.h>
#define pb emplace_back
#define mp make_pair
using namespace std;
typedef long long ll;
const ll maxn=1000007,p=998244353;
ll n,D,c[maxn],s[maxn],ans,frac[maxn],inv[maxn];
ll qpow(ll a,ll b){ll E=1; for(;b;b>>=1,a=a*a%p)if(b&1) E=E*a%p; return E;}
void init(void){
frac[0]=1;
for(ll i=1;i<maxn;i++) frac[i]=frac[i-1]*i%p;
inv[maxn-1]=qpow(frac[maxn-1],p-2);
for(ll i=maxn-1;i>=1;i--) inv[i-1]=inv[i]*i%p;
}
ll C(ll a,ll b){return (a<b||b<0)?0:frac[a]*inv[b]%p*inv[a-b]%p;}
int main(void){
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
ios::sync_with_stdio(0),cin.tie(0);
cin>>n>>D,init();
for(ll i=1,x;i<=n;i++) cin>>x,c[x]++;
for(ll i=1;i<maxn;i++) s[i]=s[i-1]+c[i];
ans=1;
for(ll i=maxn-1;i>=1;i--)if(c[i]) ans=ans*C(s[min(maxn-1,i+D)]-s[i-1],c[i])%p;
cout<<ans<<"\n";
return 0;
}
::::