Loading

Codeforces Round #656 (Div. 3) D. a-Good String(前缀和/递归)

You are given a string s[1…n]s[1…n] consisting of lowercase Latin letters. It is guaranteed that n=2kn=2k for some integer k≥0k≥0 .

The string s[1…n]s[1…n] is called cc -good if at least one of the following three conditions is satisfied:

  • The length of ss is 11 , and it consists of the character cc (i.e. s1=cs1=c );
  • The length of ss is greater than 11 , the first half of the string consists of only the character cc (i.e. s1=s2=⋯=sn2=cs1=s2=⋯=sn2=c ) and the second half of the string (i.e. the string sn2+1sn2+2…snsn2+1sn2+2…sn ) is a (c+1)(c+1) -good string;
  • The length of ss is greater than 11 , the second half of the string consists of only the character cc (i.e. sn2+1=sn2+2=⋯=sn=csn2+1=sn2+2=⋯=sn=c ) and the first half of the string (i.e. the string s1s2…sn2s1s2…sn2 ) is a (c+1)(c+1) -good string.

For example: "aabc" is 'a'-good, "ffgheeee" is 'e'-good.

In one move, you can choose one index ii from 11 to nn and replace sisi 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 ss (i.e. cc -good string for c=c= 'a'). It is guaranteed that the answer always exists.

You have to answer tt independent test cases.

Another example of an 'a'-good string is as follows. Consider the string 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.

Input

The first line of the input contains one integer tt (1≤t≤2⋅1041≤t≤2⋅104 ) — the number of test cases. Then tt test cases follow.

The first line of the test case contains one integer nn (1≤n≤131 0721≤n≤131 072 ) — the length of ss . It is guaranteed that n=2kn=2k for some integer k≥0k≥0 . The second line of the test case contains the string ss consisting of nn lowercase Latin letters.

It is guaranteed that the sum of nn does not exceed 2⋅1052⋅105 (∑n≤2⋅105∑n≤2⋅105 ).

Output

For each test case, print the answer — the minimum number of moves required to obtain an 'a'-good string from ss (i.e. cc -good string with c=c= 'a'). It is guaranteed that the answer exists.

Example

Input

Copy

6

8

bbdcaaaa

8

asdfghjk

8

ceaaaabb

8

bbaaddcc

1

z

2

ac

Output

Copy

0

7

4

5

1

1

大意就是给定一个串a,每次将这个串的某一个字母替换成任意字母,求最小操作次数使得这个串变成一个 ’a’ - 好串 ,其中 c - 好串 的定义为:这个串的前半段/后半段全为字母c,并且后半段/前半段为 (c+1) – 好串。如aaaacdbb。

暴力递归即可。首先预处理出这个字符串26个字母的前缀和。设函数func(x, l, r)的含义为:将l ~ r这一段子串变为 x – 好串需要的最少操作步骤。函数内求出把l ~ mid变为x,加上递归剩下部分的操作次数;以及把mid + 1 ~ r变为x,加上递归剩下部分的操作次数,两者取最小即可。l ~ mid变为x或者mid + 1 ~ r变为x的操作次数可以用前缀和O(1)求出。

#include <bits/stdc++.h>
using namespace std;
char s[132000];
int n, sum[132000][26];
int func(int x, int l, int r)//x代表处理到哪个字母, l和r分别为区间左右端点 
{
    if(l == r) return s[l] - 'a' == x ? 0 : 1;
    int mid = (l + r) >> 1;
    int ans = 0x3f3f3f3f;
    ans =  mid - l + 1 - (sum[mid][x] - sum[l - 1][x]) + func(x + 1, mid + 1, r);//变前半段 递归后半段 
    ans = min(ans, r - mid - (sum[r][x] - sum[mid][x]) + func(x + 1, l, mid));
    return ans;
}
int main()
{
    int t;
    cin >> t;
    while(t--)
    {
        cin >> n;
        scanf("%s", s + 1);
        for(int j = 0; j < 26; j++) sum[0][j] = 0;
        for(int i = 1; i <= n; i++)
            for(int j = 0; j < 26; j++) sum[i][j] = sum[i - 1][j] + (s[i] - 'a' == j ? 1 : 0);//三目运算别写错 
        cout << func(0, 1, n) << endl;
    }
    return 0;
}

 

posted @ 2020-07-18 17:09  脂环  阅读(384)  评论(0编辑  收藏  举报