Codeforces 660C Hard Process【二分】经典题!好题!

来源:互联网 发布:查找算法复杂度 编辑:程序博客网 时间:2024/06/05 11:40

C. Hard Process
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

You are given an array a with n elements. Each element of a is either0 or1.

Let's denote the length of the longest subsegment of consecutive elements in a, consisting of only numbers one, as f(a). You can change no more thank zeroes to ones to maximizef(a).

Input

The first line contains two integers n andk (1 ≤ n ≤ 3·105, 0 ≤ k ≤ n) — the number of elements ina and the parameter k.

The second line contains n integers ai (0 ≤ ai ≤ 1) — the elements ofa.

Output

On the first line print a non-negative integer z — the maximal value off(a) after no more thank changes of zeroes to ones.

On the second line print n integers aj — the elements of the arraya after the changes.

If there are multiple answers, you can print any one of them.

Examples
Input
7 11 0 0 1 1 0 1
Output
41 0 0 1 1 1 1
Input
10 21 0 0 1 0 1 0 1 0 1
Output
51 0 0 1 1 1 1 1 0 1

题目大意:

给你N个数,元素只有两种,要么是1,要么是0,我们最多可以让K个0变成1,让我们找连续最长子序列(元素只有1)的长度。


思路:


我们O(n)枚举这段连续最长子序列的起点,然后枚举终点。

显然直接枚举终点需要O(N^2)的总时间复杂度,是不可行的,那么考虑其特性:枚举出来的终点越远,其0的个数就越可能多,那么形成可行序列的概率就越小。

那么显然其具有一个单调性。

接下来考虑二分终点,那么目标时间复杂度O(NLogN);

那么接下来我们只要维护一个区间前缀和即可,设定为pre【i】,表示区间【1,i】中有多少个0.

那么对于我们枚举出来的起点和终点,如果其中包含0的个数小于等于K个,那么此区间就有可能是解区间,维护最大那个即可。


Ac代码:

#include<stdio.h>#include<string.h>using namespace std;int a[1000060];int pre[1000060];int main(){    int n,k;    while(~scanf("%d%d",&n,&k))    {        memset(pre,0,sizeof(pre));        for(int i=1;i<=n;i++)        {            scanf("%d",&a[i]);            pre[i]=pre[i-1];            if(a[i]==0)pre[i]++;        }        int s=-1;        int e=-1;        int ans=0;        for(int i=1;i<=n;i++)        {            int l=i;            int r=n;            while(r-l>=0)            {                int mid=(l+r)/2;                if(pre[mid]-pre[i-1]<=k)                {                    if(ans<mid-i+1)                    {                        ans=mid-i+1;                        s=i;e=mid;                    }                    l=mid+1;                }                else r=mid-1;            }        }        printf("%d\n",ans);        for(int i=1;i<=n;i++)        {            if(i>=s&&i<=e)            {                printf("1 ");            }            else printf("%d ",a[i]);        }        printf("\n");    }}






0 0