给定一个有小写字母构成的字符串S。定义F(S)表示本质不同的连续子串的集合,如F("abba") = { "a","b","ab","ba","bb","abb","bba","abba" }。
定义G(S)表示本质不同的非连续子串集合。如G("abba") = { "a","b","ab","ba","bb","abb","bba","abba" ,"aa","aba"}=F(S)∪ { "aa","aba" }。显然,F(S)是G(S)的子集。
但是对于有些字符串很奇怪,它的F(S)=G(S),例如S="abb",因为F(S)=G(S)={ "a","b","ab","bb","abb" },我们称这样的字符串为奇怪字符串。
现在L给你一个字符串S,请你求出F(S)中有多少个元素是奇怪字符串。
首先奇怪字符串不可能存在不相邻的相同字符,接下来在此基础上推出奇怪字符串不可能存在大于两种字符。
对于只有一种字符的奇怪字符串直接取最大值计数即可,有两种的需要特殊处理,看代码画图自己推吧(
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int N=2e5+5; string s; vector<pair<ll,int> > vec; vector<pair<ll,ll> > pl[26][26]; ll si[26]; pair<ll,ll> tem[N]; int main() { ios::sync_with_stdio(false); cin.tie(0); int nn; cin>>s; nn=s.length(); for(int i=0;i<nn;i++) { if(!i||s[i]!=s[i-1]) { if(i) si[s[i-1]-'a']=max(si[s[i-1]-'a'],vec.back().first); vec.push_back({1,s[i]-'a'}); } else ++vec.back().first; } si[s[nn-1]-'a']=max(si[s[nn-1]-'a'],vec.back().first); ll ans=0; int n2=vec.size(); for(int i=0;i<26;i++) ans+=si[i]; for(int i=1;i<n2;i++) pl[vec[i-1].second][vec[i].second].push_back({vec[i-1].first,vec[i].first}); for(int i=0;i<26;i++) for(int j=0;j<26;j++) if(!pl[i][j].empty()) { int nt=pl[i][j].size(); for(int e=0;e<nt;e++) { tem[e].first=pl[i][j][e].first; tem[e].second=pl[i][j][e].second; } sort(tem,tem+nt,greater<pair<ll,ll> >()); ll maxh=0; for(int e=0;e<nt;e++) { if(!e) { ans+=tem[e].first*tem[e].second; maxh=tem[e].second; } else if(tem[e].second>maxh) { ans+=tem[e].first*(tem[e].second-maxh); maxh=tem[e].second; } } } cout<<ans; return 0; }
标签:abb,tem,abba,int,问题,字符串,奇怪 From: https://www.cnblogs.com/eggome/p/17436770.html