#P1492. 2023.08.26-OPPO第三题-塔子哥的字符串(值贡献法)
题目内容
塔子哥对于一个字符串的权值定义为一个字符串中 "tzzt"
的子串的数量。例如,"tzzt"
的权值为\(1\),"tzztzzt"
的权值为 \(2\),"tzzzt"
的权值为 \(0\) 。
现在,塔子哥给你一个仅由 't'
和 'z'
构成的字符串,问你这个字符串的所有子串的权值之和。
输入描述
第一行,一个只由 't'
和 z
构成的字符串
字符串长度不超过 \(2\times 10^5\)
输出描述
一个整数,表示这个字符串的所有子串的权值之和。
样例
输入
tzztzzt
输出
8
说明
s[1,4]="tzzt"
,权值为 \(1\)
s[1,5]="tzztz"
,权值为 \(1\)
s[1,6]="tzztzz"
,权值为 \(1\)
s[1,7]="tzztzzt"
,权值为 \(2\)
s[2,7]="zztzzt"
,权值为 \(1\)
s[3,7]="ztzzt"
,权值为 \(1\)
s[4,7]="tzzt"
,权值为 \(1\)
权值之和为 \(8\)
考虑字符串中每个 tzzt
对答案的贡献。
下标从 0 开始。假设是 s[i, i+3] = "tzzt",那么这个 tzzt 对于答案的贡献为:所有 l<=i,r>=i+3 的字符串。
这样的字符串一共有 \((l+1) \times (n-r)\) 个。
累加起来即可。
时间复杂度:O(n)
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=1e5+100;
char a[maxn];
/**
tzztzzt
8
**/
int main(){
string s;
cin>>s;
int n=s.size();
long long int ans=0;
for(int i=0;i+4<=n;i++){
if(s.substr(i,4)=="tzzt"){
int l=i+1;
int r=n-1-(i+3)+1;
ans+=1ll*l*r;
}
}
cout<<ans<<endl;
return 0;
}