codeforces 1385 D. a-Good String 分治

每次将字符串分成两段,取修改左边和修改右边的最小值
分治处理即可

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<stack>
#include<queue>
using namespace std;
typedef long long ll;

const int maxn = 200010;

int T,n,m;
char s[maxn];
//sl[maxn],sr[maxn];

int calc(int l,int r,char ch){
	if(l+1==r){
		return s[l]!=ch;
	} 

	int cnt1 = 0,cnt2 = 0;
	int mid = (l+r)>>1;
	for(int i=l;i<r;++i){
		if(i<mid) cnt1 += (s[i] != ch);
		else cnt2 += (s[i] != ch);
	}
	return min(cnt1+calc(mid,r,ch+1),cnt2+calc(l,mid,ch+1));
}

ll read(){ ll s=0,f=1; char ch=getchar(); while(ch<'0' || ch>'9'){ if(ch=='-') f=-1; ch=getchar(); } while(ch>='0' && ch<='9'){ s=s*10+ch-'0'; ch=getchar(); } return s*f; }

int main(){
	T = read();	
	while(T--){
		n = read();
		scanf("%s",s);
		printf("%d\n",calc(0,n,'a'));
	} 

	return 0;
}
posted @ 2020-10-14 22:49  Tartarus_li  阅读(77)  评论(0编辑  收藏  举报