分块+二分小题目

ABC300-F

题意:

给定m个由n个相同串s拼接成的ox串,允许删除k个x,求最长的连续o

思路:

显然需要删除连续的x,观察得到答案为一段s的后缀+若干个s+一段s的前缀

枚举前缀,知道整块的信息,通过二分求出后缀。在这过程中取max即可

值得注意的是这样做的前提是ox串足够长来构造出这种形式的答案

int n,m,k;
void solve(){
    cin>>n>>m>>k;
    string s;cin>>s;s=" "+s;
    int ans=0;
    int sum=0;  
    vector<int>pre(n+1);
    rep(i,1,n){
        pre[i]=pre[i-1]+(s[i]=='x');
        sum+=(s[i]=='x');
    }
    if(sum==0){
        cout<<n*m<<endl;return;
    }

    rep(i,1,n){
        if(k>pre[n]-pre[i-1]){
            int temp=k-(pre[n]-pre[i-1]);
            int res=0;res+=(n-i+1);
            int a=temp/sum;
            temp%=sum;
            a=min(a,m-1);
            res+=a*n;
            if(m-(a+1)){
                int l=1,r=n;
                int kt=0;
                while(l<=r){
                    int mid=l+r>>1;
                    if(pre[mid]-pre[0]<=temp){
                        kt=mid;
                        l=mid+1;
                    }else r=mid-1;
                }
                res+=kt;
            }

            ans=max(ans,res);
        }else{
            int l=i,r=n;
            int res=0;
            while(l<=r){
                int mid=l+r>>1;
                if(pre[mid]-pre[i-1]<=k){
                    res=mid;
                    l=mid+1;
                }else r=mid-1;
            }
         
            ans=max(ans,res-i+1);
        }
    }
posted @ 2025-05-27 18:07  Marinaco  阅读(21)  评论(0)    收藏  举报
//雪花飘落效果