子串分值

image

思路

首先要想到:求字母的贡献度。
可以发现:对于某个字母,只有当该字母个数在子串中个数为1才会有贡献度。

以ababc为例:

  • 第一个a只有在"a","ab"中才是唯一的a,贡献1。
  • 第二个a 只有在"ba","a","bab","babc","ab","abc"中贡献1
  • 对于最后一个c,其在"ababc","babc","abc","bc","c"中都有1点贡献度。

于是只要遍历一遍,计算每个字符上的贡献度即可。

具体来说就是:字母x的左右两边出发,分别计算移动了多远才会出现一个字母与A相同,然后停止遍历,记录下步长left和right。然后算总贡献度。
贡献度的计算 一个字符的贡献度便是包含一个此字符的子字符串个数,公式即是\((左边的间隔+1)*(右边的间隔+1)\)

代码

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e4 + 10;
int n;
vector<int>  vec[33];
signed main()
{
    string s;cin>>s;
    for(int i=0;i<s.size();i++){
        vec[s[i]-'a'].push_back(i+1);
    }
    long long ans=0;
    for(int i=0;i<26;i++){
        if(vec[i].size()){
            if(vec[i].size()==1) ans+=s.length();
            else{
                for(int j=0;j<vec[i].size();j++){
                    if(j==0)
                        ans+=(vec[i][j] )  *  (vec[i][j+1]-vec[i][j])  ;
                    else if(j==(vec[i].size()-1))
                        ans+=(vec[i][j]-vec[i][j-1])  *   (s.length()-vec[i][j]+1);
                    else
                        ans+=(vec[i][j]-vec[i][j-1])  *   (vec[i][j+1]-vec[i][j]);
                }
            }
        }
    }
    cout<<ans<<endl;
    return 0;
}
posted @ 2023-03-20 21:31  kingwzun  阅读(70)  评论(0编辑  收藏  举报