D. a-Good String Codeforces Round 656 (Div. 3)

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

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

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

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

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

You have to answer t� independent test cases.

Another example of an 'a'-good string is as follows. Consider the string 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 t� (1≤t≤2⋅1041≤�≤2⋅104) — the number of test cases. Then t� test cases follow.

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

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

Output

For each test case, print the answer — the minimum number of moves required to obtain an 'a'-good string from s� (i.e. c�-good string with 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到z,问至少要改变多少个字母?

思路:

从最小段往上和并,计算当前区块最少需要改变多少字符。

方法:

深搜到最小段,往上返回当前情况最少需要改变多少字符。

核心的搜索:

ll dfs(ll l ,ll r ,char c){//左边界,右边界,当前层数对应的字符 
	if(l == r)return s[l] != c;//遍历到单个,如果不是当前深度相应字符,更改当前字符 
	ll mid = l+r >> 1;//分两半 
	ll sumx = dfs(l ,mid ,c+1);//搜前一半 
	ll sumy = dfs(mid+1 ,r ,c+1);//搜后一半 
	for(ll i = l ; i <= mid ; i ++)sumy+=(s[i] != c);//前一半合并搜完的后一半 
	for(ll i = mid+1 ; i <= r ; i ++)sumx+=(s[i] != c);//后一半合并搜完的前一半 
	return min(sumx,sumy);//取小值 
}
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define endl "\n"

string s;

ll dfs(ll l ,ll r ,char c){//左边界,右边界,当前层数对应的字符 
	if(l == r)return s[l] != c;//遍历到单个,如果不是当前深度相应字符,更改当前字符 
	ll mid = l+r >> 1;//分两半 
	ll sumx = dfs(l ,mid ,c+1);//搜前一半 
	ll sumy = dfs(mid+1 ,r ,c+1);//搜后一半 
	for(ll i = l ; i <= mid ; i ++)sumy+=(s[i] != c);//前一半合并搜完的后一半 
	for(ll i = mid+1 ; i <= r ; i ++)sumx+=(s[i] != c);//后一半合并搜完的前一半 
	return min(sumx,sumy);//取小值 
}

void solve(){
	ll x;
	cin >> x >> s;
	cout << dfs(0,x-1,'a') << endl;
	return ;
}

int main(){
	ll t=1;cin >> t;
	while(t --)solve();
	return 0;
}
  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值