cf386 C. Diverse Substrings

题意:

给定小写字母字符串,对所有 k,计算恰含 k 种字符的子串数量。

串长3e5

思路:

三指针 \(l,r1,r2\),对每个固定的 \(l\)\(r1\) 为使子串恰含 k 种字符的最左位置,\(r2\) 为使子串恰含 k+1 种字符的最左位置。易知 \(r1,r2\)\(l\) 单调增。答案为 \(r2-r1\)

vector<ll> ans;
void cal(int k) {
    vector<int> c(26, 0);
    ll res = 0; int ty = 0;
    for(int l = 1, r1 = 0, r2 = 1; l <= n; l++) {
        //r1指针
        while(ty < k && r1 < n)
            if(++c[s[++r1]-'a'] == 1) ty++;
        if(ty < k) break;
        //r2指针
        r2 = max(r2, r1);
        while(c[s[r2]-'a'] && r2 <= n) r2++;
        //统计答案
        res += r2 - r1;
        //删除左端点
        if(--c[s[l]-'a'] == 0) ty--;
    }
    if(res) ans.pb(res);
}

signed main() {
    iofast;
    cin >> s + 1; n = strlen(s + 1);

    for(int i = 1; i <= 26; i++)
        cal(i);

    cout << ans.size() << endl;
    for(ll i : ans) cout << i << endl;
}

posted @ 2022-03-24 16:27  Bellala  阅读(77)  评论(0)    收藏  举报