问题描述
小M拿到了一个仅由小写字母组成的字符串,她想知道在这个字符串中,有多少个子序列的首尾字符相同。子序列的定义是:从原字符串中按原顺序取出若干字符(可以不连续)组成的新字符串。
例如,对于字符串 "arcaea",其子序列包括 "aca", "ara", "aaa" 等,这些子序列的首尾字符都是相同的。
你需要计算满足这一条件的子序列数量,并输出对 998244353998244353 取模的结果
思路
首先,对于每一个首尾相同的字符串子序列,不妨设其起始和终止的字母的坐标为i,j。则可知:
- i <= j
- s[i] == s[j]
- 假设j和i之间有n个数,则存在2^(n)个以i,j开头结尾的满足要求的子序列
所以我们可以记住每一个字母的全部出现坐标,再计算所有可能的i,j组的计数 最后,不要忘记每一个字母单拿出来也是一个答案(即i==j),要特殊的考虑。
代码示例
int M = 998244353;
long time(long a, long b) {
return (a*b)%M;
}
long add(long a, long b) {
return (a+b)%M;
}
int solution(std::string s) {
if(!s.size()) {
return 0;
}
vector<int> pow2(s.size());
pow2[0]=1;
for(int i=1;i<s.size();i++) {
pow2[i] = time(pow2[i-1],2);
}
int res = s.size();
vector<vector<int>> pos(26);
for(int i=0;i<s.size();i++) {
for(auto x:pos[s[i]-'a']) {
res = add(res,pow2[i-x-1]);
}
pos[s[i]-'a'].push_back(i);
//cout << i <<" " <<res <<"\n";
}
return res;
}
代码示例
int M = 998244353; long time(long a, long b) { return (a*b)%M; } long add(long a, long b) { return (a+b)%M; }
int solution(std::string s) { if(!s.size()) { return 0; } vector pow2(s.size()); pow2[0]=1; for(int i=1;i<s.size();i++) { pow2[i] = time(pow2[i-1],2); } int res = s.size(); vector<vector> pos(26); for(int i=0;i<s.size();i++) { for(auto x:pos[s[i]-'a']) { res = add(res,pow2[i-x-1]); } pos[s[i]-'a'].push_back(i); //cout << i <<" " <<res <<"\n"; } return res; } int M = 998244353; long time(long a, long b) { return (a*b)%M; } long add(long a, long b) { return (a+b)%M; }
int solution(std::string s) { if(!s.size()) { return 0; } vector pow2(s.size()); pow2[0]=1; for(int i=1;i<s.size();i++) { pow2[i] = time(pow2[i-1],2); } int res = s.size(); vector<vector> pos(26); for(int i=0;i<s.size();i++) { for(auto x:pos[s[i]-'a']) { res = add(res,pow2[i-x-1]); } pos[s[i]-'a'].push_back(i); //cout << i <<" " <<res <<"\n"; } return res; } int M = 998244353; long time(long a, long b) { return (a*b)%M; } long add(long a, long b) { return (a+b)%M; }
int solution(std::string s) { if(!s.size()) { return 0; } vector pow2(s.size()); pow2[0]=1; for(int i=1;i<s.size();i++) { pow2[i] = time(pow2[i-1],2); } int res = s.size(); vector<vector> pos(26); for(int i=0;i<s.size();i++) { for(auto x:pos[s[i]-'a']) { res = add(res,pow2[i-x-1]); } pos[s[i]-'a'].push_back(i); //cout << i <<" " <<res <<"\n"; } return res; }