Codeforces660C题解

截至2019/10/16跑到了Luogu最优解Rank11, 有生之年有生之年.

Description

给你一个数组,其中有n个元素。每个元素不是0就是1。 现在可以进行k次操作,每次操作可以改变数组中的一个元素(只能改成0或1)。 请你求出操作后最长连续1的序列的长度,并输出操作后的序列。

Samples

Input #1

1
2
7 1
1 0 0 1 1 0 1

Output #1

1
2
4
1 0 0 1 1 1 1

Input #2

1
2
10 2
1 0 0 1 0 1 0 1 0 1

Output #2

1
2
5
1 0 0 1 1 1 1 1 0 1

Hint

( 1<=n<=3*10^5,0<=k<=n)

Solution

首先显然的一个暴力就是枚举$[l, r]$, 求其中0的个数是否$\leq k$, 复杂度$\mathcal O(n^3)$

考虑优化, 如果用一个前缀和记录一下0的个数, 可以优化到$\mathcal O(n^2)$, 但还是比较屑.

换个思路, 一个想法是对于一个含0的区间,我们把0都换掉一定是最优的.

那么考虑双指针维护一下当前找到的含0个数$<k$中最大的区间, 如果右面还有0那就动右指针, 区间内0的个数$>$k就动左指针.

然后时间复杂度$\mathcal O(n)$, 不过至今不知道最优解是咋写的.

Code

Upd: 最近本人码风智障, 除快读部分的[]都会被替换为<::>

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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
/* Headers */
#include<algorithm>
#include<iostream>
#include<cstring>
#include<climits>
#include<cstdio>
#include<cctype>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#define FOR(i,a,b,c) for(int i=(a);i<=(b);i+=(c))
#define ROF(i,a,b,c) for(int i=(a);i>=(b);i-=(c))
#define FORL(i,a,b,c) for(long long i=(a);i<=(b);i+=(c))
#define ROFL(i,a,b,c) for(long long i=(a);i>=(b);i-=(c))
#define FORR(i,a,b,c) for(register int i=(a);i<=(b);i+=(c))
#define ROFR(i,a,b,c) for(register int i=(a);i>=(b);i-=(c))
#define PXFR(f,g,a,b) for(register int f=1,g=1;g<=a;g+=(b))
#define lowbit(x) x&(-x)
#define LeftChild(x) x<<1
#define RightChild(x) (x<<1)+1
#define RevEdge(x) x^1
#define FILE_IN(x) freopen(x,"r",stdin);
#define FILE_OUT(x) freopen(x,"w",stdout);
#define CLOSE_IN() fclose(stdin);
#define CLOSE_OUT() fclose(stdout);
#define IOS(x) std::ios::sync_with_stdio(x)
#define Dividing() printf("-----------------------------------\n");
namespace FastIO{
const int BUFSIZE = 1 << 20;
char ibuf[BUFSIZE],*is = ibuf,*its = ibuf;
char obuf[BUFSIZE],*os = obuf,*ot = obuf + BUFSIZE;
inline char getch(){
if(is == its)
its = (is = ibuf)+fread(ibuf,1,BUFSIZE,stdin);
return (is == its)?EOF:*is++;
}
inline int getint(){
int res = 0,neg = 0,ch = getch();
while(!(isdigit(ch) || ch == '-') && ch != EOF)
ch = getch();
if(ch == '-'){
neg = 1;ch = getch();
}
while(isdigit(ch)){
res = (res << 3) + (res << 1)+ (ch - '0');
ch = getch();
}
return neg?-res:res;
}
inline void flush(){
fwrite(obuf,1,os - obuf,stdout);
os = obuf;
}
inline void putch(char ch){
*os++ = ch;
if(os == ot) flush();
}
inline void putint(int res){
static char q[10];
if(res == 0) putch('0');
else if(res < 0){putch('-');res = -res;}
int top = 0;
while(res){
q[top++] = res % 10 + '0';
res /= 10;
}
while(top--) putch(q[top]);
}
inline void space(bool x){
if(!x) putch('\n');
else putch(' ');
}
}
inline void read(int &x){
int rt = FastIO::getint();
x = rt;
}
inline void print(int x,bool enter){
FastIO::putint(x);
FastIO::flush();
FastIO::space(enter);
}
/* definitions */
const int MAXN = 3e5 + 10;
int n, k, ans, cnt, ql, qr;
bool a<:MAXN:>;
/* functions */
int main(int argc,char *argv[]){
scanf("%d %d", &n, &k);
FORR(i, 1, n, 1) scanf("%d", &a<:i:>);
PXFR(l, r, n, 1) {
cnt += !a<:r:>;
if(cnt > k) {cnt -= !a<:l:>; l++;}
if(r - l + 1 > ans) ans = r - l + 1, ql = l, qr = r;
}
for(; ql <= qr; ql++) a<:ql:> = 1;
print(ans, false);
FORR(i, 1, n, 1) print(a<:i:>, true);
return 0;
}

THE END