CF1555D Say No to Palindromes
阿新 • • 發佈:2021-09-13
暴力&構造 day2
題意:
字符集為{a,b,c}的長為\(n,(n\le 2e5)\)的字串,每次修改可以把某個位置上的字母改成{a,b,c}中的任意一個。
\(m, (m \le 2e5)\)次詢問,每次詢問一個子串最少要進行多少次修改,使得這個字串中不包含長度大於等於2的迴文串。
sol:
考慮構造長度任意的非迴文字串,將原串改成這個串,並統計每個位置上的修改次數,將區間詢問轉為求區間和。
注意到\(s_i \ne s_{i-1}\)且\(s_i \ne s_{i-2}\),那麼一定有\(s_i=s_{i-3}\)。所以非迴文的字串一定是以形如abc的字串作為迴圈節的。列舉每種迴圈節並生成字串,並詢問區間修改次數即可。
// Problem: D. Say No to Palindromes // Contest: Codeforces - Educational Codeforces Round 112 (Rated for Div. 2) // URL: https://codeforces.com/problemset/problem/1555/D // Memory Limit: 256 MB // Time Limit: 2000 ms // // Powered by CP Editor (https://cpeditor.org) #include<bits/stdc++.h> using namespace std; const int maxn = 2e5 + 7; #define ll long long int n, m, k, tot; struct _ { int l, r, ans; }q[maxn]; int rd() { int s = 0, f = 1; char c = getchar(); while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();} while (c >= '0' && c <= '9') {s = s * 10 + c - '0'; c = getchar();} return s * f; } char s[maxn]; char ch[3] = {'a','b','c'}; int a[3] = {0, 1, 2}, cnt[maxn]; int main() { n = rd(); m = rd(); scanf("%s", s + 1); for (int i = 1; i <= m; i++) { q[i].l = rd(); q[i].r = rd(); q[i].ans = maxn; } do { for (int i = 1; i <= n; i++) { if (s[i] != ch[a[i%3]]) cnt[i] = 1; else cnt[i] = 0; } for (int i = 1; i <= n; i++) cnt[i] += cnt[i-1]; for (int i = 1; i <= m; i++) q[i].ans = min(q[i].ans, cnt[q[i].r]-cnt[q[i].l-1]); }while (next_permutation(a,a+3)); for (int i = 1; i <= m; i++) printf("%d\n", q[i].ans); return 0; }