题目链接:https://codeforc.es/contest/660/problem/C
题意:给你一个长度为n的01字符串,你可以最多把k个0改成1,问最长的连续为1的子串的长度。
题解:n和k的范围都是3e5,时间限制为1s,所以我们考虑nlogn的复杂度,或者更低的复杂度。
前缀和加二分。
对每一个i二分查找最远的满足条件的j,使得[i,j]之间用光k,[i,j]之间全部为1,
同时用mxlen记录区间长度,用L,R记录最大[i,j]的边界。
简单附代码:
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define Pair pair<int,int>
#define int long long
#define fir first
#define sec second
namespace fastIO{
#define BUF_SIZE 100000
#define OUT_SIZE 100000
//fread->read
bool IOerror=0;
//inline char nc(){char ch=getchar();if(ch==-1)IOerror=1;return ch;}
inline char nc(){
static char buf[BUF_SIZE],*p1=buf+BUF_SIZE,*pend=buf+BUF_SIZE;
if(p1==pend){
p1=buf;pend=buf+fread(buf,1,BUF_SIZE,stdin);
if(pend==p1){IOerror=1;return -1;}
}
return *p1++;
}
inline bool blank(char ch){return ch==' '||ch=='\n'||ch=='\r'||ch=='\t';}
template<class T> inline bool read(T &x){
bool sign=0;char ch=nc();x=0;
for(;blank(ch);ch=nc());
if(IOerror)return false;
if(ch=='-')sign=1,ch=nc();
for(;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
if(sign)x=-x;
return true;
}
inline bool read(double &x){
bool sign=0;char ch=nc();x=0;
for(;blank(ch);ch=nc());
if(IOerror)return false;
if(ch=='-')sign=1,ch=nc();
for(;ch>='0'&&ch<='9';ch=nc())x=x*10+ch-'0';
if(ch=='.'){double tmp=1; ch=nc();for(;ch>='0'&&ch<='9';ch=nc())tmp/=10.0,x+=tmp*(ch-'0');}
if(sign)x=-x;return true;
}
inline bool read(char *s){
char ch=nc();
for(;blank(ch);ch=nc());
if(IOerror)return false;
for(;!blank(ch)&&!IOerror;ch=nc())*s++=ch;
*s=0;
return true;
}
inline bool read(char &c){
for(c=nc();blank(c);c=nc());
if(IOerror){c=-1;return false;}
return true;
}
template<class T,class... U>bool read(T& h,U&... t){return read(h)&&read(t...);}
#undef OUT_SIZE
#undef BUF_SIZE
};using namespace fastIO;using namespace std;
const int N=3e5+5;
const double eps=1e-7;
const double pi=acos(-1.0);
const int mod=998244353;
int C[N],sum[N],P[N];
signed main(){
int n,k;read(n,k);
for(int i=1;i<=n;i++){
read(C[i]);
sum[i]=sum[i-1];
if(C[i]==0)sum[i]++;
}
int L=0,R=0,mxlen=0;
for(int i=1;i<=n;i++){
int l=i,r=n;
while(l<=r){
int mid=(l+r)/2;
if(sum[mid]-sum[i-1]<=k){
l=mid+1;
if(mid-i+1>mxlen){
mxlen=mid-i+1;
L=i;R=mid;
}
}
else r=mid-1;
}
}
printf("%lld\n",mxlen);
for(int i=1;i<=n;i++){
if(i<=R && i>=L)printf("1 ");
else printf("%lld ",C[i]);
}
return 0;
}