分块+二分小题目
题意:
给定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);
}
}

浙公网安备 33010602011771号