Bedao Mini Contest 06 - GIRLS
===
[Link](https://oj.vnoi.info/problem/bedao_m06_girls)
-----
### Hướng dẫn
Vì mình cần chọn ra $N$ người có độ chênh lệch giữa người lớn nhất và người bé nhất không quá $K$ nên khi xác định ra được người có giá trị nhỏ nhất $A$ và lớn nhất $B$ thì thêm vô những người có giá trị $X$ nằm giữa $[A, B]$ sẽ không làm thay đổi độ chênh lệch.
Vậy ta chỉ cần sắp xếp lại mảng theo giá trị tăng dần, chọn các đoạn $[l, r]$ gồm $N$ người và kiểm tra xem đoạn này có thỏa điều kiện $max(a[l \dots r]) - min(a[l \dots r]) = a[r] - a[l] \leq K$ hay không
Để tính tổng giá trị của một đoạn $(a[l] + a[l + 1] + ... + a[r])$ thì ta chỉ cần xây dựng mảng cộng dồn và ta có thể tính giá trị một đoạn trong $O(1)$
Vậy bài này có thể làm trong $O(n\ log\ n)$, trong đó
- $O(n\ log\ n)$ để sắp xếp
- $O(n)$ để dựng mảng cộng dồn
- $O(n)$ để duyệt qua các đoạn và cập nhật kết quả
------
### Code
> **Time:** $O(n log n)$
> **Space:** $O(n)$
> **Algo:** Sorting, Implementation, Partial Sum, Two Pointers
```cpp=
#include <algorithm>
#include <iostream>
using namespace std;
typedef long long ll;
const int LIM = 1e6 + 16;
ll f[LIM];
int a[LIM];
int main()
{
/// De nhap du lieu nhanh hon
ios::sync_with_stdio(NULL);
cin.tie(NULL);
/// Input
int n, d, k;
cin >> n >> d >> k;
for (int i = 1; i <= n; ++i)
cin >> a[i];
/// Sort gia tri
sort(a + 1, a + n + 1);
/// Dung mang cong don
f[0] = 0;
for (int i = 1; i <= n; ++i)
f[i] = f[i - 1] + a[i];
/// Tinh gia tri
ll best = -2;
for (int l = 1, r = d; r <= n; ++l, ++r) /// duyet qua cac doan [l, r] co do dai (d)
{
if (a[r] - a[l] <= k) /// thoa dieu kien
{
best = max(best, f[r] - f[l - 1]);
}
}
/// Output
cout << best;
return 0;
}
```