[Acwing蓝桥杯DP] 2872. 子串分值和
题目大意:给一个长度为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!!!

浙公网安备 33010602011771号