QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#268343 | #5084. Longest Substring | STnofarjo# | TL | 1ms | 3512kb | C++20 | 4.1kb | 2023-11-28 16:01:01 | 2023-11-28 16:01:01 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define rep(i,a,b) for (int i=(a); i<(b); ++i)
typedef vector<int> vi;
struct SuffixArray {
vi sa, lcp;
SuffixArray(string &s, int lim = 256) {
int n = sz(s) + 1, k = 0, a, b;
vi x(all(s)+1), y(n), ws(max(n, lim)), rank(n);
sa = lcp = y, iota(all(sa), 0);
for (int j=0, p=0; p<n; j=max(1,j*2), lim=p) {
p = j, iota(all(y), n-j);
rep(i,0,n) if (sa[i] >= j) y[p++] = sa[i] - j;
fill(all(ws), 0);
rep(i,0,n) ws[x[i]]++;
rep(i,1,lim) ws[i] += ws[i-1];
for (int i=n; i--;) sa[--ws[x[y[i]]]] = y[i];
swap(x, y), p = 1, x[sa[0]] = 0;
rep(i,1,n) a = sa[i-1], b = sa[i], x[b] = (y[a] == y[b] && y[a+j] == y[b+j]) ? p-1 : p++;
}
rep(i,1,n) rank[sa[i]] = i;
for (int i=0, j; i<n-1; lcp[rank[i++]] = k)
for (k && k--, j=sa[rank[i]-1]; s[i+k] == s[j+k]; k++);
}
};
int main() {
ios_base::sync_with_stdio(0); cin.tie(0);
string s;
cin >> s;
int n = s.size();
SuffixArray sa(s);
// for (int i=1; i<=n; i++) cout << sa.sa[i] << ' ';
// cout << '\n';
// for (int i=1; i<=n; i++) cout << sa.lcp[i] << ' ';
// cout << '\n';
vector<int> par(n+1), sez(n+1), lb(n+1), rb(n+1), lst(n+1);
vector<pair<int, int>> ans(n+1, make_pair(0, 0));
vector<set<int>> vals(n+1);
vector<map<int, int>> diffs(n+1);
auto create = [&](int u, int h) -> void {
par[u] = lb[u] = rb[u] = u; sez[u] = 1; vals[u].insert(sa.sa[u]);
lst[u] = h;
};
auto find = [&](auto self, int u) -> int {
if (u != par[u]) return par[u] = self(self, par[u]);
return u;
};
auto unite_set = [&](int u, int v) -> void {
auto &val = vals[v];
// auto &diff = diffs[v];
for (int x : vals[u]) {
// auto it = val.lower_bound(x);
// if (it != val.begin()) {
// auto prv = it;
// prv--;
// int y = *it - *prv;
// diff[y]--;
// if (diff[y] == 0) diff.erase(y);
// }
val.insert(x);
// it = val.lower_bound(x);
// if (it != val.end()) {
// auto nxt = it;
// nxt++;
// if (nxt != val.end()) {
// int y = *nxt - x;
// diff[y]++;
// }
// if (it != val.begin()) {
// auto prv = it;
// prv--;
// int y = x - *prv;
// diff[y]++;
// }
// }
}
vals[u].clear();
// diffs[u].clear();
};
auto calc = [&](int u, int h) -> int {
int ret = 0, lst = -1;
for (int l : vals[u]) {
if (l > lst) {
ret++;
lst = l + h - 1;
}
}
return ret;
};
auto update_ans = [&](int u, int h) -> void {
if (h+1 > lst[u]) return;
int len = rb[u] - lb[u] + 1;
// cout << lb[u] << ' ' << rb[u] << ' ' << len << ' ' << h+1 << ' ';
// cout << (diffs[u].empty() ? 1000 : diffs[u].begin()->first) << '\n';
// int d = (diffs[u].empty() ? 1000000003 : diffs[u].begin()->first);
// if (ans[len] == 0 && d >= h+1) {
// cout << lb[u] << ' ' << rb[u] << ' ' << len << ' ' << min(d, lst[u]) << '\n';
// ans[len] = min(d, lst[u]);
// }
int lo = h+2, hi = lst[u];
pair<int, int> best(calc(u, lo), h+1);
while (lo <= hi) {
int mid = (lo + hi) / 2;
int res = calc(u, mid);
if (res == best.first) {
best.second = mid;
lo = mid + 1;
} else {
hi = mid - 1;
}
}
ans[len] = max(ans[len], best);
};
auto unite = [&](int u, int v, int h) -> void {
u = find(find, u); v = find(find, v);
update_ans(u, h); update_ans(v, h);
if (sez[u] > sez[v]) swap(u, v);
par[u] = v; sez[v] += sez[u]; lb[v] = min(lb[u], lb[v]); rb[v] = max(rb[u], rb[v]); lst[v] = h;
unite_set(u, v);
};
vector<int> pos(n);
for (int i=1; i<=n; i++) pos[sa.sa[i]] = i;
vector<int> idx(n+1);
for (int i=0; i<=n; i++) idx[i] = i;
sort(idx.begin()+1, idx.end(), [&](int i, int j) {
return sa.lcp[i] > sa.lcp[j];
});
for (int h=n, i=1; h>0; h--) {
create(pos[n - h], h);
while (i <= n && sa.lcp[idx[i]] >= h) {
int j = idx[i];
unite(j, j-1, h);
i++;
}
}
for (int i=1; i<=n; i++) {
if (i == par[i]) update_ans(i, 0);
}
// ans[1] = n;
for (int i=1; i<=n; i++) cout << ans[i].second << ' ';
cout << '\n';
return 0;
}
詳細信息
Test #1:
score: 100
Accepted
time: 1ms
memory: 3496kb
input:
ababa
output:
5 2 1 0 0
result:
ok single line: '5 2 1 0 0 '
Test #2:
score: 0
Accepted
time: 0ms
memory: 3400kb
input:
aaaaaaaa
output:
8 7 6 5 4 3 2 1
result:
ok single line: '8 7 6 5 4 3 2 1 '
Test #3:
score: 0
Accepted
time: 1ms
memory: 3512kb
input:
a
output:
1
result:
ok single line: '1 '
Test #4:
score: 0
Accepted
time: 0ms
memory: 3472kb
input:
abcdefghijklmnopqrstuvwxyz
output:
26 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
result:
ok single line: '26 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 '
Test #5:
score: -100
Time Limit Exceeded
input:
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...