2872. 子串分值和

题目链接

2872. 子串分值和

对于一个字符串 \(S\) ,我们定义 \(S\) 的分值 \(f(S)\)\(S\) 中出现的不同的字符个数。
例如 \(f(" a b a ")=2, f(" a b c ")=3, f(" a a a ")=1\)
现在给定一个字符串 \(S[0 . . n-1]\) (长度为 \(n\) ),请你计算对于所有 \(S\) 的非空子串 \(S[i . . j](0 \leq i \leq j<n)\)\(f(S[i . . j])\) 的和是多少。

输入格式

输入一行包含一个由小写字母组成的字符串 \(S\)

输出格式

输出一个整数表示答案。

数据范围

对于 \(20 \%\) 的评测用例, \(1 \leq n \leq 10\)
对于 \(40 \%\) 的评测用例, \(1 \leq n \leq 100\)
对于 \(50 \%\) 的评测用例, \(1 \leq n \leq 1000\)
对于 \(60 \%\) 的评测用例, \(1 \leq n \leq 10000\)
对于所有评测用例, \(1 \leq n \leq 100000\)

输入样例:

ababc

输出样例:

28

样例解释

子串 f值
a     1
ab    2
aba   2
abab  2
ababc 3
 b    1
 ba   2
 bab  2
 babc 3
  a   1
  ab  2
  abc 3
   b  1
   bc 2
    c 1

解题思路

思维

考虑每一个字符的贡献,先复制上一个字符的贡献,加上当前字符作为唯一出现的贡献,即与上次出现的距离,该字符上次出现前的贡献已经统计在了复制的贡献中了

  • 时间复杂度:\(O(n)\)

代码

#include<bits/stdc++.h>
#define fi first
#define se second
#define help {cin.tie(NULL);cout.tie(NULL);}
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
typedef pair<LL,LL> PLL;
template <typename T> bool chkMax(T &x,T y){return (x<y?x=y,1:0);}
template <typename T> bool chkMin(T &x,T y){return (x>y?x=y,1:0);}


template <typename T> inline void read(T &x)
{
    int f=1;x=0;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();
    }
    while(s>='0'&&s<='9'){x+=x*10+(s^48),s=getchar();
    }
    x*=f;
}

string s;
int p[26],cnt[26];
int main()
{
    cin>>s;
    int n=s.size();
    s=' '+s;
    LL res=0;
    int lst=0;
    for(int i=1;i<=n;i++)
    {
        int t=s[i]-'a'; 
        lst+=i-p[t];
        res+=lst;
        p[t]=i;
    }
    cout<<res;
    return 0;
}
posted @ 2022-03-20 18:10  zyy2001  阅读(137)  评论(2编辑  收藏  举报