Say No to Palindromes
题意:
给一个长度为n的字符串,只包含abc三种字符,现在有m次询问,每次询问给出l,r,问l~r需要操作几次使得其不包括长度大于等于2的回文子串,每次操作可以改变一个字符,当然,只能在abc三种字符中改变。例如,a只能变成b或c。
思路:
因为要不存在长度大于等于2的回文子串,所以相邻的字符不能相同,又因为字符串只包含abc三种字符,所以不难发现,字符串只能由"abc"“acb”“bac”“bca”“cab”"cba"这六种子串组成,因此可以令f[j][i]表示前i个字符,当前匹配第j种子串,不合法的字符数,即需要的操作数,对于每次询问,枚举6种子串, ans = min(ans, f[j][r] - f[j][l - 1])即可。
代码:
/*************************************************************************
> File Name: c.cpp
> Author: Beans
> Mail: 3112748286@qq.com
> Created Time: 2023/5/25 16:49:12
************************************************************************/
#include <iostream>
#include <algorithm>
#define int long long
#define endl '\n'
using namespace std;
const int maxn = 3e5 + 7;
int n, m;
string s[6] = {
"abc", "acb", "bac", "bca", "cab", "cba"
};
int f[6][maxn];
void solve(){
cin >> n >> m;
string a;
cin >> a;
a = " " + a;
for(int i = 1; i <= n; i ++ ){
for(int j = 0; j < 6; j ++ ){
f[j][i] = f[j][i - 1] + (a[i] != s[j][(i - 1) % 3]);
}
}
while(m -- ){
int l, r;
cin >> l >> r;
int ans = 0x3f3f3f3f;
for(int i = 0; i < 6; i ++ )
ans = min(ans, f[i][r] - f[i][l - 1]);
cout << ans << endl;
}
}
signed main(){
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int t = 1;
//cin >> t;
while(t -- )
solve();
}