QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#390769 | #5312. Levenshtein Distance | jiajia | RE | 2ms | 5488kb | C++20 | 2.7kb | 2024-04-15 21:25:59 | 2024-04-15 21:25:59 |
Judging History
answer
#include <bits/stdc++.h>
#define LL long long
using namespace std;
const int MAXN = 4e5 + 5;
int n, m, K;
struct SA {
string s;
int n, m, sa[MAXN], tmp[MAXN << 1], rk[MAXN], cnt[MAXN];
void tsort() {
for (int i = 0; i <= m; i++) cnt[i] = 0;
for (int i = 1; i <= n; i++) cnt[rk[i]]++;
for (int i = 1; i <= m; i++) cnt[i] += cnt[i - 1];
for (int i = n; i >= 1; i--) sa[cnt[rk[tmp[i]]]--] = tmp[i];
}
bool cmp(int x, int y, int w) {return tmp[x] == tmp[y] && tmp[x + w] == tmp[y + w];}
int h[18][MAXN];
void build() {
for (int i = 1; i <= n; i++) rk[i] = s[i], tmp[i] = i;
m = 200, tsort();
for (int w = 1, p = 0; p < n; w <<= 1, m = p) {
p = 0;
for (int i = 1; i <= w; i++) tmp[++p] = n - w + i;
for (int i = 1; i <= n; i++) if (sa[i] > w) tmp[++p] = sa[i] - w;
tsort();
memcpy(tmp, rk, sizeof(rk));
rk[sa[1]] = p = 1;
for (int i = 2; i <= n; i++) {
if (cmp(sa[i], sa[i - 1], w)) rk[sa[i]] = p;
else rk[sa[i]] = ++p;
}
}
if (K == 30) return;
for (int i = 1, p = 0; i <= n; i++) {
if (rk[i] == 1) continue;
if (p) --p;
while (s[i + p] == s[sa[rk[i] - 1] + p]) ++p;
h[0][rk[i]] = p;
}
for (int i = 1; i <= 17; i++)
for (int j = 1; j + (1 << i) - 1 <= n; j++)
h[i][j] = min(h[i - 1][j], h[i - 1][j + (1 << i - 1)]);
}
}sa;
string s, t;
int lcp(int i, int j) {
if (i > n || j > m) return 0;
i = sa.rk[i], j = sa.rk[n + 1 + j];
if (i > j) swap(i, j);
++i;
int k = __builtin_clz(j - i + 1) ^ 31;
return min(sa.h[k][i], sa.h[k][j - (1 << k) + 1]);
}
int f[65][35], ans[MAXN];
int main() {
// freopen("in.txt", "r", stdin);
ios::sync_with_stdio(0), cin.tie(0);
cin >> K >> s >> t, n = s.size(), m = t.size(), s = ' ' + s, t = ' ' + t;
for (int i = 1; i <= n; i++) sa.s[i] = s[i];
sa.s[n + 1] = '$';
for (int i = 1; i <= m; i++) sa.s[n + 1 + i] = t[i];
sa.n = n + m + 1, sa.build();
if (K == 30) return 0;
for (int p = 0; p < m; p++) {
memset(f, 0xc0, sizeof(f));
f[0][K] = 0;
for (int i = 0; i <= K; i++)
for (int j = max(-K, 1 - n); j <= min(K, m - p - 1); j++) {
if (f[i][j + K] < 0) continue;
f[i][j + K] += lcp(f[i][j + K] + 1, f[i][j + K] + 1 + j + p);
if (i == K) continue;
f[i + 1][j + K] = max(f[i + 1][j + K], f[i][j + K] + 1);
f[i + 1][j + K + 1] = max(f[i + 1][j + K + 1], f[i][j + K]);
f[i + 1][j + K - 1] = max(f[i + 1][j + K - 1], f[i][j + K] + 1);
}
for (int j = max(-K, 1 - n); j <= min(K, m - p - n); j++)
for (int i = 0; i <= K; i++)
if (f[i][j + K] >= n) {ans[i]++; break;}
}
for (int i = 0; i <= K; i++) cout << ans[i] << '\n';
cerr << (double)clock() / CLOCKS_PER_SEC << endl;
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 2ms
memory: 5488kb
input:
4 aaa aabbaab
output:
0 5 15 7 1
result:
ok 5 number(s): "0 5 15 7 1"
Test #2:
score: -100
Runtime Error
input:
30 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA...