题目地址:
https://www.luogu.com.cn/problem/CF1385D
题目描述:
定义:字符串s
为一个c-好串
(c 为一个字符)时,必须满足:
- 当 ∣ s ∣ = 1 |s| = 1 ∣s∣=1 , s = c s = c s=c
- 当
∣
s
∣
>
1
|s| > 1
∣s∣>1,
s
s
s 的左半部分为全为
c
c
c,右半部分为一个
(c+1)-好串
或者 s s s 的右半部分为全为 c c c,左半部分为一个(c+1)-好串
其中
∣
s
∣
|s|
∣s∣ 代表 字符串
s
s
s 的长度。
举个例子:当
s
=
“
c
d
b
b
a
a
a
a
"
s=“cdbbaaaa"
s=“cdbbaaaa"时,
s
s
s 是一个 a-好串
现在,给你一个字符串
s
s
s (
∣
s
∣
=
2
k
|s| = 2^k
∣s∣=2k ),问最少替换多少个字符,使其为一个 a-好串
。
题目描述:
You are given a string
s
[
1
…
n
]
s[1 \dots n]
s[1…n] consisting of lowercase Latin letters. It is guaranteed that
n
=
2
k
n = 2^k
n=2k for some integer
k
≥
0
k \ge 0
k≥0 .
The string s [ 1 … n ] s[1 \dots n] s[1…n] is called c c c -good if at least one of the following three conditions is satisfied:
- The length of s s s is 1 1 1 , and it consists of the character c c c (i.e. s 1 = c s_1=c s1=c );
- The length of s s s is greater than 1 1 1 , the first half of the string consists of only the character c c c (i.e. s 1 = s 2 = ⋯ = s n 2 = c s_1=s_2=\dots=s_{\frac{n}{2}}=c s1=s2=⋯=s2n=c ) and the second half of the string (i.e. the string s n 2 + 1 s n 2 + 2 … s n s_{\frac{n}{2} + 1}s_{\frac{n}{2} + 2} \dots s_n s2n+1s2n+2…sn ) is a ( c + 1 ) (c+1) (c+1) -good string;
- The length of s s s is greater than 1 1 1 , the second half of the string consists of only the character c c c (i.e. s n 2 + 1 = s n 2 + 2 = ⋯ = s n = c s_{\frac{n}{2} + 1}=s_{\frac{n}{2} + 2}=\dots=s_n=c s2n+1=s2n+2=⋯=sn=c ) and the first half of the string (i.e. the string s 1 s 2 … s n 2 s_1s_2 \dots s_{\frac{n}{2}} s1s2…s2n ) is a ( c + 1 ) (c+1) (c+1) -good string.
For example: “aabc” is ‘a’-good, “ffgheeee” is ‘e’-good.
In one move, you can choose one index i i i from 1 1 1 to n n n and replace s i s_i si with any lowercase Latin letter (any character from ‘a’ to ‘z’).
Your task is to find the minimum number of moves required to obtain an ‘a’-good string from s s s (i.e. c c c -good string for c = c= c= ‘a’). It is guaranteed that the answer always exists.
You have to answer t t t independent test cases.
Another example of an ‘a’-good string is as follows. Consider the string s = s = s= “cdbbaaaa”. It is an ‘a’-good string, because:
- the second half of the string (“aaaa”) consists of only the character ‘a’;
- the first half of the string (“cdbb”) is ‘b’-good string, because:
- the second half of the string (“bb”) consists of only the character ‘b’;
- the first half of the string (“cd”) is ‘c’-good string, because:
- the first half of the string (“c”) consists of only the character ‘c’;
- the second half of the string (“d”) is ‘d’-good string.
输入格式:
The first line of the input contains one integer
t
t
t (
1
≤
t
≤
2
⋅
1
0
4
1 \le t \le 2 \cdot 10^4
1≤t≤2⋅104 ) — the number of test cases. Then
t
t
t test cases follow.
The first line of the test case contains one integer n n n ( 1 ≤ n ≤ 131 072 1 \le n \le 131~072 1≤n≤131 072 ) — the length of s s s . It is guaranteed that n = 2 k n = 2^k n=2k for some integer k ≥ 0 k \ge 0 k≥0 . The second line of the test case contains the string s s s consisting of n n n lowercase Latin letters.
It is guaranteed that the sum of n n n does not exceed 2 ⋅ 1 0 5 2\cdot 10^5 2⋅105 ( ∑ n ≤ 2 ⋅ 1 0 5 \sum n \le 2 \cdot 10^5 ∑n≤2⋅105 ).
输出格式:
For each test case, print the answer — the minimum number of moves required to obtain an ‘a’-good string from
s
s
s (i.e.
c
c
c -good string with
c
=
c =
c= ‘a’). It is guaranteed that the answer exists.
思路是分治。代码如下:
#include <iostream>
using namespace std;
const int N = 2e5 + 10;
int n;
char s[N];
int dfs(int l, int r, char x) {
if (l == r) return x == s[l] ? 0 : 1;
int mid = l + (r - l >> 1);
int y1 = 0, y2 = 0;
for (int i = l; i <= mid; i++)
if (s[i] != x) y1++;
for (int i = mid + 1; i <= r; i++)
if (s[i] != x) y2++;
return min(y1 + dfs(mid + 1, r, x + 1), y2 + dfs(l, mid, x + 1));
}
int main() {
int T;
scanf("%d", &T);
while (T--) {
scanf("%d%s", &n, s + 1);
printf("%d\n", dfs(1, n, 'a'));
}
}
每组数据时间复杂度 O ( n log n ) O(n\log n) O(nlogn),空间 O ( log n ) O(\log n) O(logn)。