CF567D
思路 $1$:一眼 set
维护区间的模板。每次打击一个位置就把区间分裂,重新统计贡献—— $[l,r]$ 这个闭区间最多能放的战舰数为 $\lfloor\frac{(r-l+1)+1}{a+1}\rfloor$($a+1$ 是因为战舰之间有空格)。
思路 $2$:二分答案。其中判断答案是否合法就只需要拿出所有未被打击格子组成的极大闭区间,按照上述方式统计是否放得下 $k$ 艘战舰即可。
#include <bits/stdc++.h>
#define FL(i, a, b) for(int i = (a); i <= (b); i++)
#define FR(i, a, b) for(int i = (a); i >= (b); i--)
using namespace std;
const int N = 2e5 + 10;
int n, k, a, m, cnt, now, x[N], b[N];
int check(int mid){
fill(b + 1, b + n + 1, 0), cnt = now = 0;
FL(i, 1, mid) b[x[i]] = 1;
FL(i, 1, n){
if(b[i]) cnt += (now + 1) / (a + 1), now = 0;
else now++;
}
return (cnt += (now + 1) / (a + 1)) < k;
}
int main(){
scanf("%d%d%d%d", &n, &k, &a, &m);
FL(i, 1, m) scanf("%d", &x[i]);
int l = 1, r = m, ans = -1;
while(l <= r){
int mid = l + r >> 1;
if(check(mid)) ans = mid, r = mid - 1;
else l = mid + 1;
}
printf("%d\n", ans);
return 0;
}