题解:P10810 【MX-S2-T1】变
首先,题面明示二分(让循环节最小)。
我们很容易就可以想到二分枚举循环节长度。假设循环节长度为
但是我们会想到一个问题:如果
我们知道,办法总比困难多。
我们知道,如果
我们不妨来一个夸张的估算,假设
我写了个程序,测得
所以,这个算法平均时间复杂度为
当然,最坏情况下依然能取到
#include<bits/stdc++.h>
#error Don't copy the solution!
using namespace std;
int k, cnt;
vector<int> ys;
string s;
int buk[300];
int work(int x){
for (int i = 1; i <= x; i++)
if (x % i == 0){
cnt++;
ys.push_back(i);
}
return cnt - 1;
}
bool check(int x){
int u = ys[x], sum = 0;
for (int i = 1; i <= u; i++){
memset(buk, 0, sizeof buk);
for (int j = i; j < s.size(); j += u)
buk[s[j] - 'a']++;
sort(buk, buk + 26, [](int a, int b){return a > b;});
int tot = (s.size() - 1) / u;
sum += (tot - buk[0]);
}
if (sum <= k)
return 1;
else
return 0;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin >> k;
cin >> s;
s = " " + s;
int l = 0, r = work(s.size() - 1), ans = r;
while (l <= r){
int mid = (l + r) >> 1;
if (check(mid))
ans = mid, r = mid - 1;
else
l = mid + 1;
}
cout << ys[ans];
return 0;
}