arc140 A - Right String

题意:

给定字符串 \(s\)。定义 \(t(i)\) 表示字符串 \(s_i,s_{i+1},\dots,s_n,s_1,s_2,\dots,s_{i-1}\)

\(s\) 的价值为所有不同的 \(t(i),i=1,\dots,n\) 的数量。可以修改至多 \(k\) 个字符,最小化 \(s\) 的价值

思路:

假设某两个串一样:\(g(i)=g(j),i<j\)

那么 \(g(i+1)=g(j+1)\)

以此类推,一直到 \(g(i+(j-i))=g(j+(j-i))\),即 \(g(i)=g(j)=g(j+(j-i))\)

所有有个周期!只有 \(g(i),g(i+1),\dots,g(j-1)\)\(j-i\) 个不同的值

枚举 \(n\) 的长度的因子 \(d\),暴力改变 \(s\) 其循环节为 \(d\),价值就是 \(d\)

const signed N = 3 + 4e5;
int n, k; string s;

bool ok(int d, int k) {
    vector<vector<int>> cnt(d, vector<int>(26, 0));
    for(int i = 0; i < n; i++) cnt[i%d][s[i]-'a']++;
    for(int i = 0; i < d && k >= 0; i++) //其他字符都变成出现次数最多者
        k -= n/d - *max_element(all(cnt[i]));
    return k >= 0;
}

void sol() {
    cin >> n >> k >> s;

    int ans = n;
    for(int i = 1; i <= n / i; i++) if(n % i == 0) {
        if(ok(i, k)) ans = min(ans, i);
        if(ok(n/i, k)) ans = min(ans, n/i);
    }
    cout << ans;
}
posted @ 2022-06-10 17:31  Bellala  阅读(37)  评论(0)    收藏  举报