题解:CF1188C Array Beauty

· · 题解

Array Beauty

这道题目有两个关键的 trick:

转移直接双指针 + 前缀和即可,我称之为 双前组合

The code

#include<bits/stdc++.h>

#define L(i, a, b) for(int i = (a); i <= (b); i++)
#define R(i, a, b) for(int i = (a); i >= (b); i--)
#define ll long long

using namespace std;

const int N = 1005 + 10;
const int mod = 998244353;

ll a[N], n, k, ans[1000001], F[1005][N], sum[N][N];

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);  cout.tie(0);
    cin >> n >> k;
    L(i, 1, n) cin >> a[i];
    sort(a+1, a+n+1);
    R(i, (a[n]-a[1])/(k-1), 0) {
        F[0][0] = sum[0][0] = 1;
        int p = 0;
        L(j, 1, n) {
            while(p < j && a[j] - a[p+1] >= i) p++;
            L(x, 0, k) {
                if(x) F[j][x] = sum[p][x-1];
                sum[j][x] = (sum[j-1][x] + F[j][x]) % mod;
            }
            ans[i] = (ans[i] + F[j][k]) % mod;
        }
//      cout << ans[i] << '\n';
    }
    ll Ans = 0;
    R(i, (a[n]-a[1])/(k-1), 0)
      Ans = (Ans + 1LL * (ans[i] - ans[i+1] + mod) % mod * i % mod) % mod;
    cout << Ans << '\n';
    return 0;
}