B题 离散化+双指针
最后找到的最大区间一定是以某一个点开始的,遍历每个数,看哪个数满足,复杂度2e9
优化:
排序之后把连在一起的一块当作一个点,两个连在一块的段中间没有数的块也当作一个点,记录这些块的长度,变为5e6复杂度,最大区间一定是以某一个块的第一个数为起点开始的。双指针维护每个块为起点能到达的最远距离。
#include<bits/stdc++.h>
using namespace std;
const int M = 1000010;
const int N = 500010;
int a[N];
int idx ;
long long n,m,k;
struct Node{
int l,r,v;
}b[M];
int main(){
ios::sync_with_stdio();
cin.tie(0);
cout.tie(0);
cin>>n>>m>>k;
for(int i=0;i<n;i++){
cin>>a[i];
}
sort(a,a+n);
int* nn = unique(a,a+n);
n = nn - a;
b[0] = {a[0],a[0],1};
int right = a[0];
for(int i=1;i<n;i++){
if(a[i]-1 != right){
idx++;
b[idx] = {right+1,a[i]-1,0};
idx++;
b[idx] = {a[i],a[i],1};
right = a[i];
}else{
b[idx].r = a[i];
right = a[i];
}
}
long long res = 0;
long long zero_cnt = 0;
long long this_res = 0;
int i,j;
for(i=0,j=0;i<=j && i<=idx && j<=idx;i++){
while(j <= idx){
int j_zero=0,j_one=0;
if(b[j].v == 1){
j_one = b[j].r - b[j].l +1;
}else{
j_one = b[j].r - b[j].l +1;
j_zero = b[j].r - b[j].l +1;
}
if(zero_cnt + j_zero >k){
break;
}else{
zero_cnt += j_zero;
this_res += j_one;
j++;
}
}
long long val_res = min(m, this_res + k - zero_cnt);
res = max(res,val_res);
int i_zero=0,i_one = 0;
if(b[i].v == 1){
i_one = b[i].r - b[i].l +1;
}else{
i_one = b[i].r - b[i].l +1;
i_zero = b[i].r - b[i].l +1;
}
if(i<j){
zero_cnt -= i_zero;
this_res -= i_one;
}else{
j=i+1;
}
}
cout<<res;
}
