题目不是我搬的。
记cic_ici表示iii之前比pip_ipi大的数的个数。合法的PPP的步数下界是∑i=1nmax(ci−K,0)\sum_{i=1}^n\max(c_i-K,0)∑i=1nmax(ci−K,0)。并且可以注意到,{{ci}∣ci<i}\{\{c_i\}|c_i<i\}{{ci}∣ci<i}与序列PPP形成双射关系。
显然下界是能取到的。难点在于观察到。发现d(P,P′)d(P,P')d(P,P′)不好刻画,但是我们能得到形式化的构造过程:从左往右考虑,如果ci′>Kc_i'>Kci′>K那么就把iii向前移ci−Kc_i-Kci−K个位置。结合题意,我们得到PPP中ci<Kc_i<Kci<K的点没有移动,那么我们只需求出PPP中ci=Kc_i=Kci=K的点能向后移动的距离然后乘起来即可。事实上因为后面的数都比pip_ipi大所以答案是∏ci=K(n−i+1)\prod_{c_i=K}(n-i+1)∏ci=K(n−i+1)。复杂度O(n2)O(n^2)O(n2)。
#include<bits/stdc++.h>
#define pb push_back
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
const int mod=998244353;
int n,K,p[5005];
ll mul=1;
int main(){
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
cin>>n>>K;for(int i=1;i<=n;i++)cin>>p[i];
for(int i=1;i<=n;i++){
int l=0;for(int j=1;j<i;j++)if(p[j]>p[i])l++;
if(l>K){
cout<<0;
return 0;
}
if(l==K){
int r=1;
for(int j=i+1;j<=n;j++){
if(p[j]>p[i])r++;
else break;
}mul=mul*r%mod;
}
}cout<<mul;
}