专栏文章
反思
个人记录参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @miqb4sq5
- 此快照首次捕获于
- 2025/12/04 01:55 3 个月前
- 此快照最后确认于
- 2025/12/04 01:55 3 个月前
P4045 [JSOI2009] 密码
这道题考察 AC自动机。
关于多个字符串匹配可以考虑到 AC自动机 上跑 DP。
有几点注意:
-
注意 Fail 树的祖先是已经跑过的子串。
-
在记忆化的时候:区分 -1、0、1。尽量使用
==号区分,不容易出错。 -
dfs 输出方案时要先保存在数组中,很多时候不能边输出边递归。
P5410 【模板】扩展 KMP/exKMP(Z 函数)
思想:和 马拉车差不多,把前面已经算过的直接套用。
功能:求一个字符串 的所有后缀 与文本 的 LCP(最长公共前缀)。
有一些要关注点:
-
字符串下标从 1 开始时要注意细节,尤其重构代码时。
-
算时用了
long long结果返回值用了int。建议使用auto作为返回值。
#include <bits/stdc++.h>
using namespace std;
void exkmp(string s) {
vector<int> z;
int n = s.size();
z.resize(n); z[0] = n;
int x = 0, p = 0;
for (int i=1; i<n; ++i) {
z[i] = 0;
int l = z[i-x];
if (i <= p) z[i] = min(l, p-i+1);
while (i+z[i] < n && s[z[i]] == s[i+z[i]]) ++z[i];
if (i+z[i]-1 > p) x = i, p = i+z[i]-1;
}
}
auto cal() {
long long ret = 0;
for (int i=0; i<z.size(); ++i) {
ret ^= (long long)(i+1)*(z[i]+1);
}
return ret;
}
signed main() {
ios::sync_with_stdio(0);
cin.tie(0);
string a, b;
cin >> a >> b;
exkmp(b);
cout << cal() << '\n';
exkmp(b+"#"+a);
z.erase(z.begin(), z.begin()+b.size()+1);
cout << cal() << '\n';
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...