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 ;
}

浙公网安备 33010602011771号