hdu 7055

https://acm.hdu.edu.cn/showproblem.php?pid=7055
题目问每个子串中每种字母的个数的平方的累加和
每个字母单独统计,\(ans = \sum_{i=1}^n\sum_{j=i}^n(s[j] - s[i - 1])^2\)
化简:\(= n\sum_{i=1}^n{s[i]}^2 - (\sum_{i=1}^ns[i])^2 + \sum_{i=1}^n{s[i]}^2\)
因为对于每种字母只有在当前位置是这种字母的时候才会改变\(s[i]\),那么可以将下标存起来,\(O(n)\)求解

const int maxn = 1e5 + 10;
const int mod = 998244353;
char s[maxn];
int len, ans = 0, v[26][maxn], sz[26];
int calc(int id) {
    int sum1 = 0, sum2 = 0, pre = 1;
    for(int i = 0; i < sz[id]; ++ i) {
        sum1 += (v[id][i] - pre) * i % mod;
        sum2 += (v[id][i] - pre) * i * i % mod;
        pre = v[id][i];
    }
    sum1 %= mod;    sum2 %= mod;
    return (len + 1) * sum2 % mod - sum1 * sum1 % mod + mod;
}

void run() {
    cin >> s + 1;
    len = strlen(s + 1);    ans = 0;
    for(int i = 0; i < 26; ++ i)   sz[i] = 0;
    for(int i = 1; i <= len; ++ i)
        v[s[i] - 'a'][sz[s[i] - 'a'] ++] = i;
    for(int i = 0; i < 26; ++ i)   v[i][sz[i] ++] = len + 1;
    for(int i = 0; i < 26; ++ i)    ans += calc(i) % mod;
    cout << ans % mod << '\n';
    return ;
}
posted @ 2021-09-14 15:06  wlhp  阅读(22)  评论(0)    收藏  举报