题意:一个长度为n的串str,q个询问,每个询问给出整数m和字符ch,问:给出m次修改字符的机会,能得到的str中字母ch的子段最长长度是多少?1<=n<=1500, 1<=m<=n, 1<=q<=200000
思路:尺取,维护 修改了 m个 非ch字符 的子段,当 l+1 和 r+1 的位置都不是ch,令 l++,r++(两头同时右移,始终保持花费为m),在尺取的过程中时刻取最大值,r移动到n为止,最终答案即所求。
#include<bits/stdc++.h>
using namespace std;
char str[1505];
int cnt[26];
int main(){
int n,q,m;
scanf("%d",&n);
char ch[3];
scanf("%s",str+1);
scanf("%d",&q);
while(q--){
scanf("%d",&m);
scanf("%s",&ch);
int i,mark=m;
for(i=1;i<=n;++i){
if(str[i]!=ch[0]) --mark;
if(!mark) break;
}
int ans=min(i,n),l=1,r=i,tmp=i;
while(r<n){
while(r+1<=n&&str[r+1]==ch[0]) ++tmp,++r;//r停在需要花费1的位置 或 n的位置
ans=max(ans,tmp);
if(r==n) break;//r停在n就结束了
while(l+1<=r&&str[l]==ch[0]) --tmp,++l;//l可能停在需要花费1的位置 或 r的位置
if(str[l]!=ch[0]) ++l,++r;//l如果没停在r的位置,让l、r都++,这样就抵消了花费,继续循环
}
printf("%d\n",ans);
}
}