0
点赞
收藏
分享

微信扫一扫

ZR #1188. 【线上训练 15】字符串


题目链接:​​传送门​​(没买的看不了)

暴力的话就是枚举的子串,判断是不是这个子串的子序列,是
然后考虑枚举左端点计算右端点的贡献
先枚举一个左端点,如果一个右端点满足这个子串的子序列,那么也一定满足,所以我们需要找到这样的最小的
表示匹配到匹配到时使的子序列的最小的端点
那么更新,在的时候更新答案,这里要记下上一个不然会重复计算

#include <bits/stdc++.h>
#define
#define

using namespace std;
typedef long long ll;
int f[A][B], n, m, last; char s1[A], s2[B];
//f[i][j]表示s1匹配到i,s2匹配到j时使s2是s1的子序列的最小的端点

int main(int argc, char const *argv[]) {
cin >> n >> m >> (s1 + 1) >> (s2 + 1); ll ans = 0;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++)
if (s1[i] == s2[j]) {
if (j == 1) f[i][j] = i;
else f[i][j] = f[i - 1][j - 1];
}
else f[i][j] = f[i - 1][j];
if (s1[i] == s2[m] and f[i][m] != last)
ans += (f[i][m] - last) * (n - i + 1), last = f[i][m];
//n-i+1就是因为从r到n所有点作为右端点都满足条件
//f[i][m]-last就是当前可作为左端点的点的个数
}
cout << ans << endl;
}


举报

相关推荐

0 条评论