1. 程式人生 > >Codeforces 660C Hard Process【二分】經典題!好題!

Codeforces 660C Hard Process【二分】經典題!好題!

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 or 1.

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 maximize f(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 than k 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 1
1 0 0 1 1 0 1
Output
4
1 0 0 1 1 1 1
Input
10 2
1 0 0 1 0 1 0 1 0 1
Output
5
1 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");
    }
}