题目
给定两个字符串,在字符串 \(a\) 中找子序列,在 \(b\) 中找一个子串,询问有多少个子序列与子串相等,重复的字符串算一次。
思路
匹配和去重,想到哈希。
匹配,想到双指针。
每次枚举将要匹配的 \(b\) 数组的左端点,双指针匹配 \(a\) 数组,如果成功,那么将 \(b[i, j]\) 这一段的哈希值放入 vector,最后将 vector
排序 + 去重即可。
代码
#include <bits/stdc++.h>
using namespace std;
using ui64 = unsigned long long;
const int N = 3010;
ui64 base = 13331;
int n;
string a, b;
ui64 z[N], h[N];
ui64 query(int l, int r) {
return h[r] - h[l - 1] * z[r - l + 1];
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n;
cin >> a >> b;
a = ' ' + a;
b = ' ' + b;
h[0] = z[0] = 1;
for (int i = 1; i <= n; i++) h[i] = h[i - 1] * base + b[i];
for (int i = 1; i <= n; i++) z[i] = z[i - 1] * base;
vector<ui64> res;
for (int i = 1; i <= n; i++) {
int r = -1;
for (int j = i; j <= n; j++) {
do {
r++;
} while (a[r] != b[j] && r <= n);
if (r <= n) res.push_back(query(i, j));
}
}
sort(res.begin(), res.end());
res.erase(unique(res.begin(), res.end()), res.end());
cout << res.size() << '\n';
return 0;
}
标签:P7469,匹配,NOI,int,ui64,cin,小赛,Online,字符串
From: https://www.cnblogs.com/Yuan-Jiawei/p/18409531