1. 程式人生 > 實用技巧 >cf1385D---遞迴+字首和

cf1385D---遞迴+字首和

題目連結:https://codeforces.com/contest/1385/problem/D

簡單題意:給定一個字串s,和good string的規則(太長了就不寫了)。求至少改變多少個字元,使得s成為a-good string

直接暴力遞迴即可。考慮修改左邊和右邊分別需要的次數,取二者最小值。對於某個區間內有多少個特定字元,可以用字首和小優化一下。

#include<bits/stdc++.h>
#define ll long long
using namespace std;

const int maxn=150000+10;
int t,n,i,j,pre[30][maxn],ans;
char s[maxn];

int calc(int c,int l,int r){
	if (l>r) return 0;
    if (l==r) return (s[l]-'a'+1==c)?0:1;
	int m=(l+r)/2;
	int numl=n/(1<<c)-(pre[c][m]-pre[c][l-1]);
	int numr=n/(1<<c)-(pre[c][r]-pre[c][m]);
	return min(numl+calc(c+1,m+1,r),numr+calc(c+1,l,m));
}

int main(){
	std::ios::sync_with_stdio(false);
	cin>>t;
	while (t--){
	  cin>>n;
	  cin>>s+1;n=strlen(s+1); //*
	  for (i=1;i<=26;i++){
	  	pre[i][0]=0;
	  	for (j=1;j<=n;j++) pre[i][j]=(s[j]-'a'+1==i)?pre[i][j-1]+1:pre[i][j-1];
	  }
	  cout<<calc(1,1,n)<<endl;
	}
	return 0;
}