题意:给你一个字符串的长度n和查询次数m,再给出字符串s(只包含abc三种字母),每次查询[l,r]区间,计算最小的修改次数(将一个字符转化为abc的一种)使s在[l,r]的范围内不存在回文串(长度为2个及以上的回文串)
分析:考虑一个很长的串例如aabbcc,发现只有当将其修改为abcabc(三种字母的循环节)时才没有回文串。发现三种字母只有6种组合,所以只要将每种组合循环跟原字符串对比,有不同的就+1,取其最小修改次数即可。因为m范围在2e5,故先预处理。
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+5;
string sam[6]={"abc","acb","bac","bca","cab","cba"};
int dp[6][maxn];
int main()
{
int n,m;
cin>>n>>m;
string a;
cin>>a;
for(int i=0;i<6;i++)
{
for(int j=1;j<=n;j++)
{
dp[i][j]=dp[i][j-1]+(sam[i][(j-1)%3]!=a[j-1]);
}
}
while(m--)
{
int l,r;
cin>>l>>r;
int minn=0x3f3f3f3f;
for(int i=0;i<6;i++)
{
minn=min(minn,dp[i][r]-dp[i][l-1]);
}
cout<<minn<<endl;
}
}