[Acwing蓝桥杯DP] 2872. 子串分值和

题目链接:2872. 子串分值和 - AcWing题库

题目大意:给一个长度为n的字符串,定义f[a]为字符串a中所有不同元素数量

求该长度为n的字符串的所有子串的 f 总和,即子串分值和

数据范围:1<=n<=1e5

分析:

暴力时间复杂度O(n^2),会超时;

大概思路就是枚举每个点然后到起点的字符串的f值

用DP优化 f[ i ]表示 前 i 个字符所形成的所有子串的 f 总和值。

区域划分  f [ i - 1] | str[ i ]

考虑第i个数对前面子符串 f 总和值的影响

最多情况下,会让总和值加 i (长度),即每个子串加上1,包括本身

这种情况下是,前面的所有字符都不等于str[ i ];

如果前面有字符那么只能加上 i - 最后一个相同字符的所在位置

所以,只需要再创建一个last数组,用来记录每个字符最后出现的位置即可

代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=100000+10;
int last[N];
int f[N];
char str[N];
LL res;
int main()
{
    scanf("%s",str+1);
    int n=strlen(str+1);
    for(int i=1;i<=n;i++)
    {
        int t=str[i]-'a';
        f[i]=f[i-1]+i-last[t];
        last[t]=i;
        res+=f[i];
    }
    printf("%lld",res);   
    return 0;
}

END!!!

 

posted @ 2022-04-07 22:04  秦末  阅读(91)  评论(0)    收藏  举报
1 博文导航目录