社区讨论
我的 AC 自动机被熨斗卡常了怎么办
P14363[CSP-S 2025] 谐音替换参与者 5已保存回复 5
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 5 条
- 当前快照
- 1 份
- 快照标识符
- @mhixqs2c
- 此快照首次捕获于
- 2025/11/03 17:26 4 个月前
- 此快照最后确认于
- 2025/11/08 07:51 4 个月前
RT,95pts。
代码
CPP#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 200010, L = 5000010, W = 30;
const ll mod = 2025110249ll;
mt19937 rng (114514);
uniform_int_distribution <ll> dist (1919810ll, mod - 1919810ll);
int n, m, q, w = 27, a[L], cnt;
ll bas[L];
char s[L], t[L];
map <ll, int> mp;
namespace ac {
int nxt[L][W], fail[L], dat[L], tcnt;
void insert (int p) {
for (int i = 1; i <= cnt; i++) {
if (nxt[p][a[i]] == 0) {
nxt[p][a[i]] = ++tcnt;
}
p = nxt[p][a[i]];
}
dat[p]++;
}
queue <int> q;
void getfail (int p) {
for (int i = 1; i <= w; i++) {
if (nxt[p][i] != 0) {
fail[nxt[p][i]] = p;
q.push (nxt[p][i]);
} else {
nxt[p][i] = p;
}
}
while (!q.empty ()) {
int u = q.front ();
q.pop ();
for (int i = 1; i <= w; i++) {
if (nxt[u][i] == 0) {
nxt[u][i] = nxt[fail[u]][i];
} else {
fail[nxt[u][i]] = nxt[fail[u]][i];
q.push (nxt[u][i]);
}
}
}
}
int query (int p) {
int ret = 0;
for (int i = 1; i <= cnt; i++) {
p = nxt[p][a[i]];
for (int j = p; j != 0; j = fail[j]) {
ret += dat[j];
}
}
return ret;
}
}
int main () {
freopen ("replace.in", "r", stdin);
freopen ("replace.out", "w", stdout);
scanf ("%d%d", &n, &q);
for (int i = 1; i <= n; i++) {
scanf ("%s%s", s + 1, t + 1);
m = strlen (s + 1);
int l = -1, r = -1;
for (int j = 1; j <= m; j++) {
if (s[j] != t[j]) {
if (l == -1) {
l = j;
}
r = j;
}
}
if (l == -1 && r == -1) {
continue;
}
ll hsh = 0;
for (int j = l; j <= r; j++) {
if (bas[j - l + 1] == 0) {
bas[j - l + 1] = dist (rng);
}
ll u = (s[j] - 96) * 26 + t[j] - 96;
(hsh += u * bas[j - l + 1]) %= mod;
}
cnt = 0;
for (int j = 1; j <= m; j++) {
if (j == l) {
a[++cnt] = 27;
}
if (j >= l && j <= r) {
continue;
}
a[++cnt] = s[j] - 96;
}
int t = 0;
if (mp.count (hsh)) {
t = mp[hsh];
} else {
t = mp[hsh] = ++ac::tcnt;
}
ac::insert (t);
}
for (auto i : mp) {
ac::getfail (i.second);
}
for (int i = 1; i <= q; i++) {
scanf ("%s%s", s + 1, t + 1);
m = strlen (s + 1);
if (strlen (t + 1) != m) {
puts ("0");
continue;
}
int l = -1, r = -1;
for (int j = 1; j <= m; j++) {
if (s[j] != t[j]) {
if (l == -1) {
l = j;
}
r = j;
}
}
ll hsh = 0;
for (int j = l; j <= r; j++) {
if (bas[j - l + 1] == 0) {
bas[j - l + 1] = dist (rng);
}
int u = (s[j] - 96) * 26 + t[j] - 96;
(hsh += u * bas[j - l + 1]) %= mod;
}
if (!mp.count (hsh)) {
puts ("0");
} else {
cnt = 0;
for (int j = 1; j <= m; j++) {
if (j == l) {
a[++cnt] = 27;
}
if (j >= l && j <= r) {
continue;
}
a[++cnt] = s[j] - 96;
}
printf ("%d\n", ac::query (mp[hsh]));
}
}
return 0;
}
求问是熨斗评测机问题还是数据强度问题。
回复
共 5 条回复,欢迎继续交流。
正在加载回复...