codevs 1415 比那名居天子

题目描述看这里

最近想做一些东方的题(毕竟东方也玩了一段时间了233),而且最近在搞二分,于是乎,我阴差阳错的找到了这道题,于是发现这是一道水题,然后么。。呵呵

在写思路之前,先放一些天子的图片233(毕竟题目名字就是天子酱233)。

可爱又傲娇の天子酱QAQ

咳咳,好了言归正传,我们二分一个答案mid为更改的区间长度,然后我们每次扫一遍01串,发现一个1就把后面mid长度的值全赋为0,这样的话一开始我脑洞大开想用线段树来维护QAQ,之后发现对于n=500,000的点实在是有些吃力(线段树常数大,不解释),而且貌似每次验证完还要复原01串,这样的话常数肯定大的飞起。我们不妨再想一个方法,这个方法很机智,遇到1,直接把枚举位置跳过mid位就行了,因为该位后mid位肯定也被赋为0了,所以我们直接跳过这些无用的枚举,而且还不用复原233。这样的话,时间复杂度是O(nlogn)的(事实上还要比这个小,因为跳过枚举的原因)。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
const int maxn=5e5+5;
char ss[maxn];
int n,m;
bool check(int mid)
{
    int cnt=0;
    for(int i=1;i<=n;i++)
    {
        if(ss[i]=='1') i+=mid-1,cnt++;
    }
    if(cnt<=m) return 1;
    return 0;
}
int main()
{
    scanf("%d%d",&n,&m);
    scanf("%s",ss+1);
    int l=0,r=6e5,mid;
    while(r-l>1)
    {
        mid=l+r>>1;
        if(check(mid)) r=mid;
        else l=mid;
    }
    printf("%d
",r);
    return 0;
}
原文地址:https://www.cnblogs.com/loi-frank/p/7737406.html