题解:CF1188C Array Beauty
CuSObin_BiNSO4 · · 题解
这题我的想法倒是挺一波三折的——从想到一个会 T 的方法到发现如何优化这个方法。
首先,我们需要发现这是一道传统的拆贡献题——如果一个长度为
第一步肯定要对序列排好序,由于仅要求是子序列,所以打乱顺序不会对答案产生影响。接下来问题转化为对于所有正整数
这个比较简单:设
然后设
明显,我们倒着处理 dp 值时可以使用后缀和优化。于是对于单个
最后我们想想我们要把
但是,
这样我们
代码:
#include<bits/stdc++.h>
using namespace std;
int n,K,a[1005],nxt[1005],dp[1005][1005],pres[1005][1005],ans;
const int modp=998244353;
int main(){
cin>>n>>K;for(int i=1;i<=n;i++)cin>>a[i];
sort(a+1,a+n+1);for(int i=1;i<=n;i++)nxt[i]=i+1;
for(int o=1;o<=100000/(K-1);o++){
for(int i=1;i<=n;i++)while(nxt[i]<=n&&a[nxt[i]]-a[i]<o)nxt[i]++;
for(int i=n;i>=1;i--){
dp[i][1]=1;for(int j=2;j<=K;j++)dp[i][j]=pres[nxt[i]][j-1];
for(int j=1;j<=K;j++)pres[i][j]=(pres[i+1][j]+dp[i][j])%modp;
}
ans=(ans+pres[1][K])%modp;
}
cout<<ans;
return 0;
}