#include <bits/stdc++.h>
using namespace std;
const int N = 8e3 + 4;
string s;
int n, k, t, res = -1, base;
int biuro[N], zdalne[N], wolne[N], razem[N];
int tree[4*N];
int ile(int l, int r, bool czy_biuro) {
if (l > r) return 0;
if (czy_biuro) {
return biuro[r] - biuro[l - 1];
}
else {
return razem[r] - razem[l - 1];
}
}
void update(int x, int v) {
x += base;
tree[x] = v;
while (x > 1) {
x /= 2;
tree[x] = v;
}
}
int max_val(int v, int l, int r, int a, int b){
if (l > r || a > r || b < l) return -1;
if (a >= l && b <= r) return tree[v];
int mid = (a + b) / 2;
return max(max_val(v*2, l, r, a, mid), max_val(v*2+1, l, r, mid+1, b));
}
int main() {
cin >> n >> k >> t;
cin >> s;
for(int i = 1; i <= n; i++) {
biuro[i] = biuro[i - 1] + (s[i - 1] == '1');
zdalne[i] = zdalne[i - 1] + (s[i - 1] == '2');
wolne[i] = wolne[i - 1] + (s[i - 1] == '3');
razem[i] = biuro[i] + zdalne[i];
}
int ile_wymagane = max(0, razem[n] - k);
if (ile_wymagane <= zdalne[n]) {
res = n - ile_wymagane;
}
// i - t = kolejny przyjazd do biura który musimy dodać
// i = gdzie wstawiamy powrót do domu
else {
base = 1;
while (base < n) base *= 2;
for(int i = 1 ; i < base * 2; i++) tree[i] = -1;
for (int i = t + 1 ; i <= n - t + 1 ; i++) {
int missed_l = ile(1, i - t - 1, 1) + ile(i - t, i - 1, 0);
update(missed_l, i - 1);
int missed_r = ile(i, i + t - 1, 0) + ile(i + t, n, 1);
int can_miss = k - missed_r;
if (can_miss < 0) continue;
int max_idx = max_val(1, 0, can_miss, 0, base - 1);
if (max_idx == -1) continue;
int czas_wolny_biuro = max(0, wolne[i - 1] - wolne[max_idx]);
res = max(res, n - ile_wymagane - czas_wolny_biuro - 2*t);
}
}
cout<<res<<"\n";
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 | #include <bits/stdc++.h> using namespace std; const int N = 8e3 + 4; string s; int n, k, t, res = -1, base; int biuro[N], zdalne[N], wolne[N], razem[N]; int tree[4*N]; int ile(int l, int r, bool czy_biuro) { if (l > r) return 0; if (czy_biuro) { return biuro[r] - biuro[l - 1]; } else { return razem[r] - razem[l - 1]; } } void update(int x, int v) { x += base; tree[x] = v; while (x > 1) { x /= 2; tree[x] = v; } } int max_val(int v, int l, int r, int a, int b){ if (l > r || a > r || b < l) return -1; if (a >= l && b <= r) return tree[v]; int mid = (a + b) / 2; return max(max_val(v*2, l, r, a, mid), max_val(v*2+1, l, r, mid+1, b)); } int main() { cin >> n >> k >> t; cin >> s; for(int i = 1; i <= n; i++) { biuro[i] = biuro[i - 1] + (s[i - 1] == '1'); zdalne[i] = zdalne[i - 1] + (s[i - 1] == '2'); wolne[i] = wolne[i - 1] + (s[i - 1] == '3'); razem[i] = biuro[i] + zdalne[i]; } int ile_wymagane = max(0, razem[n] - k); if (ile_wymagane <= zdalne[n]) { res = n - ile_wymagane; } // i - t = kolejny przyjazd do biura który musimy dodać // i = gdzie wstawiamy powrót do domu else { base = 1; while (base < n) base *= 2; for(int i = 1 ; i < base * 2; i++) tree[i] = -1; for (int i = t + 1 ; i <= n - t + 1 ; i++) { int missed_l = ile(1, i - t - 1, 1) + ile(i - t, i - 1, 0); update(missed_l, i - 1); int missed_r = ile(i, i + t - 1, 0) + ile(i + t, n, 1); int can_miss = k - missed_r; if (can_miss < 0) continue; int max_idx = max_val(1, 0, can_miss, 0, base - 1); if (max_idx == -1) continue; int czas_wolny_biuro = max(0, wolne[i - 1] - wolne[max_idx]); res = max(res, n - ile_wymagane - czas_wolny_biuro - 2*t); } } cout<<res<<"\n"; } |
English