20240418
This commit is contained in:
316
ACMOJ-2132.cpp
Normal file
316
ACMOJ-2132.cpp
Normal file
@ -0,0 +1,316 @@
|
||||
#include <cstdio>
|
||||
#define unlikely(x) __builtin_expect(!!(x), 0)
|
||||
struct char_reader {
|
||||
FILE *f;
|
||||
char *buf, *p1, *p2;
|
||||
int size;
|
||||
char_reader(FILE *fin, int bufsize = 1 << 16) {
|
||||
f = fin;
|
||||
size = bufsize;
|
||||
p1 = p2 = 0;
|
||||
buf = new char[size];
|
||||
}
|
||||
~char_reader() { delete[] buf; }
|
||||
inline int operator()() {
|
||||
return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, size, f), p1 == p2)
|
||||
? EOF
|
||||
: *p1++;
|
||||
}
|
||||
};
|
||||
struct char_writer {
|
||||
FILE *f;
|
||||
char *buf, *p, *end;
|
||||
int size;
|
||||
char_writer(FILE *fout, int bufsize = 1 << 16) {
|
||||
f = fout;
|
||||
size = bufsize;
|
||||
buf = new char[size];
|
||||
p = buf;
|
||||
end = buf + bufsize;
|
||||
}
|
||||
~char_writer() {
|
||||
fwrite(buf, p - buf, 1, f);
|
||||
delete[] buf;
|
||||
}
|
||||
inline char operator()(char ch) {
|
||||
if (unlikely(end == p)) {
|
||||
fwrite(buf, end - buf, 1, f);
|
||||
p = buf;
|
||||
}
|
||||
return *p++ = ch;
|
||||
}
|
||||
};
|
||||
char_reader gch(stdin);
|
||||
char_writer wch(stdout);
|
||||
template <typename T>
|
||||
inline int read(T &t) {
|
||||
bool f = false;
|
||||
int ch;
|
||||
while (ch = gch(), !((ch >= '0' && ch <= '9') || ch == '-')) {
|
||||
if (ch == EOF) return 0;
|
||||
}
|
||||
t = 0;
|
||||
if (ch == '-') f = true, ch = gch();
|
||||
t = ch ^ 48;
|
||||
while (ch = gch(), ch >= '0' && ch <= '9')
|
||||
t = (t << 3) + (t << 1) + (ch ^ 48);
|
||||
if (f) t = -t;
|
||||
return 1;
|
||||
}
|
||||
inline int read(char &c) {
|
||||
c = 0;
|
||||
int ch;
|
||||
while (ch = gch(), (ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t')) {
|
||||
if (ch == EOF) return 0;
|
||||
}
|
||||
c = ch;
|
||||
return 1;
|
||||
}
|
||||
inline int read(char *s) {
|
||||
int ch;
|
||||
while (ch = gch(), (ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t')) {
|
||||
if (ch == EOF) return 0;
|
||||
}
|
||||
*s++ = ch;
|
||||
while (ch = gch(),
|
||||
!(ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t') && ch != EOF)
|
||||
*s++ = ch;
|
||||
*s++ = 0;
|
||||
return 1;
|
||||
}
|
||||
inline int read(const char *s) { return read((char *)s); }
|
||||
inline int readline(char *s) {
|
||||
int ch;
|
||||
while (ch = gch(), (ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t')) {
|
||||
if (ch == EOF) return 0;
|
||||
}
|
||||
*s++ = ch;
|
||||
while (ch = gch(), !(ch == '\n' || ch == '\r') && ch != EOF) *s++ = ch;
|
||||
*s++ = 0;
|
||||
return 1;
|
||||
}
|
||||
inline int readline(const char *s) { return readline((char *)s); }
|
||||
template <typename T>
|
||||
inline void write(T t) {
|
||||
int stk[20], cnt = 0;
|
||||
if (t == 0) {
|
||||
wch('0');
|
||||
return;
|
||||
}
|
||||
if (t < 0) {
|
||||
wch('-');
|
||||
t = -t;
|
||||
}
|
||||
while (t > 0) {
|
||||
stk[cnt++] = t % 10;
|
||||
t /= 10;
|
||||
}
|
||||
while (cnt) wch(stk[--cnt] + '0');
|
||||
}
|
||||
inline void write(char t) { wch(t); }
|
||||
inline void write(char *s) {
|
||||
while (*s) wch(*s++);
|
||||
}
|
||||
inline void write(const char *s) { write((char *)s); }
|
||||
#if __cplusplus >= 201103L
|
||||
template <typename T, typename... Args>
|
||||
inline int read(T &t, Args &...args) {
|
||||
return read(t) + read(args...);
|
||||
}
|
||||
template <typename T, typename... Args>
|
||||
inline void write(T t, Args... args) {
|
||||
write(t);
|
||||
write(args...);
|
||||
}
|
||||
#else
|
||||
template <typename A_t, typename B_t>
|
||||
inline int read(A_t &a, B_t &b) {
|
||||
return read(a) + read(b);
|
||||
}
|
||||
template <typename A_t, typename B_t, typename C_t>
|
||||
inline int read(A_t &a, B_t &b, C_t &c) {
|
||||
return read(a) + read(b) + read(c);
|
||||
}
|
||||
template <typename A_t, typename B_t, typename C_t, typename D_t>
|
||||
inline int read(A_t &a, B_t &b, C_t &c, D_t &d) {
|
||||
return read(a) + read(b) + read(c) + read(d);
|
||||
}
|
||||
template <typename A_t, typename B_t>
|
||||
inline void write(A_t a, B_t b) {
|
||||
write(a);
|
||||
write(b);
|
||||
}
|
||||
template <typename A_t, typename B_t, typename C_t>
|
||||
inline void write(A_t a, B_t b, C_t c) {
|
||||
write(a);
|
||||
write(b);
|
||||
write(c);
|
||||
}
|
||||
template <typename A_t, typename B_t, typename C_t, typename D_t>
|
||||
inline void write(A_t a, B_t b, C_t c, D_t d) {
|
||||
write(a);
|
||||
write(b);
|
||||
write(c);
|
||||
write(d);
|
||||
}
|
||||
#endif
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <vector>
|
||||
using namespace std;
|
||||
typedef long long LL;
|
||||
namespace __SA_IS {
|
||||
const int L_TYPE = 0;
|
||||
const int S_TYPE = 1;
|
||||
const int kMaxN = 3e5 + 10;
|
||||
const int kMaxChar = 1e6;
|
||||
int a[kMaxN * 2], sa[kMaxN * 2], typ[kMaxN * 2], c[kMaxChar * 2 + 5],
|
||||
p[kMaxN * 2], sbuc[kMaxChar + 5], lbuc[kMaxChar + 5], name[kMaxN * 2];
|
||||
|
||||
inline int islms(int *typ, int i) { return !typ[i] && (i == 1 || typ[i - 1]); }
|
||||
|
||||
int cmp(int *s, int *typ, int p, int q) {
|
||||
do {
|
||||
if (s[p] != s[q]) return 1;
|
||||
p++;
|
||||
q++;
|
||||
} while (!islms(typ, p) && !islms(typ, q));
|
||||
return (!islms(typ, p) || !islms(typ, q) || s[p] != s[q]);
|
||||
}
|
||||
|
||||
void isort(int *s, int *sa, int *typ, int *c, int n, int m) {
|
||||
int i;
|
||||
for (lbuc[0] = sbuc[0] = c[0], i = 1; i <= m; i++) {
|
||||
lbuc[i] = c[i - 1] + 1;
|
||||
sbuc[i] = c[i];
|
||||
}
|
||||
for (i = 1; i <= n; i++)
|
||||
if (sa[i] > 1 && typ[sa[i] - 1]) sa[lbuc[s[sa[i] - 1]]++] = sa[i] - 1;
|
||||
for (i = n; i >= 1; i--)
|
||||
if (sa[i] > 1 && !typ[sa[i] - 1]) sa[sbuc[s[sa[i] - 1]]--] = sa[i] - 1;
|
||||
}
|
||||
|
||||
void build_sa(int *s, int *sa, int *typ, int *c, int *p, int n, int m) {
|
||||
int i;
|
||||
for (i = 0; i <= m; i++) c[i] = 0;
|
||||
for (i = 1; i <= n; i++) c[s[i]]++;
|
||||
for (i = 1; i <= m; i++) c[i] += c[i - 1];
|
||||
typ[n] = 0;
|
||||
for (i = n - 1; i >= 1; i--)
|
||||
if (s[i] < s[i + 1])
|
||||
typ[i] = 0;
|
||||
else if (s[i] > s[i + 1])
|
||||
typ[i] = 1;
|
||||
else
|
||||
typ[i] = typ[i + 1];
|
||||
int cnt = 0;
|
||||
for (i = 1; i <= n; i++)
|
||||
if (!typ[i] && (i == 1 || typ[i - 1])) p[++cnt] = i;
|
||||
for (i = 1; i <= n; i++) sa[i] = 0;
|
||||
for (i = 0; i <= m; i++) sbuc[i] = c[i];
|
||||
for (i = 1; i <= cnt; i++) sa[sbuc[s[p[i]]]--] = p[i];
|
||||
isort(s, sa, typ, c, n, m);
|
||||
int last = 0, t = -1, x;
|
||||
for (i = 1; i <= n; i++) {
|
||||
x = sa[i];
|
||||
if (!typ[x] && (x == 1 || typ[x - 1])) {
|
||||
if (!last || cmp(s, typ, x, last))
|
||||
name[x] = ++t;
|
||||
else
|
||||
name[x] = t;
|
||||
last = x;
|
||||
}
|
||||
}
|
||||
for (i = 1; i <= cnt; i++) s[n + i] = name[p[i]];
|
||||
if (t < cnt - 1)
|
||||
build_sa(s + n, sa + n, typ + n, c + m + 1, p + n, cnt, t);
|
||||
else
|
||||
for (i = 1; i <= cnt; i++) sa[n + s[n + i] + 1] = i;
|
||||
for (i = 0; i <= m; i++) sbuc[i] = c[i];
|
||||
for (i = 1; i <= n; i++) sa[i] = 0;
|
||||
for (i = cnt; i >= 1; i--) sa[sbuc[s[p[sa[n + i]]]]--] = p[sa[n + i]];
|
||||
isort(s, sa, typ, c, n, m);
|
||||
}
|
||||
} // namespace __SA_IS
|
||||
void SA_IS(int *s, int n, int *sa, int *rk) {
|
||||
using namespace __SA_IS;
|
||||
for (int i = 1; i <= n; i++) a[i] = s[i];
|
||||
a[++n] = 0;
|
||||
build_sa(a, sa, typ, c, p, n, kMaxChar);
|
||||
n--;
|
||||
for (int i = 1; i <= n; i++) sa[i] = sa[i + 1];
|
||||
for (int i = 1; i <= n; i++) rk[sa[i]] = i;
|
||||
}
|
||||
void computeHeight(int *s, int n, int *sa, int *rk, int *height) {
|
||||
int k = 0;
|
||||
for (int i = 1; i <= n; i++) {
|
||||
if (rk[i] == 1) {
|
||||
height[rk[i]] = 0;
|
||||
continue;
|
||||
}
|
||||
if (k > 0) { k--; }
|
||||
int j = sa[rk[i] - 1];
|
||||
while (i + k <= n && j + k <= n && s[i + k] == s[j + k]) { k++; }
|
||||
height[rk[i]] = k;
|
||||
}
|
||||
}
|
||||
const int kMaxN = 3e5 + 10;
|
||||
int n;
|
||||
int str[kMaxN << 2], sa[kMaxN << 2], rnk[kMaxN << 2], height[kMaxN], res[kMaxN];
|
||||
const int kInf = 0x3f3f3f3f;
|
||||
int main() {
|
||||
#ifdef local
|
||||
freopen("pro.in", "r", stdin);
|
||||
#endif
|
||||
read(n);
|
||||
for (int i = 1; i <= n; i++) read(str[i]);
|
||||
SA_IS(str, n, sa, rnk);
|
||||
computeHeight(str, n, sa, rnk, height);
|
||||
vector<int> sa2, height2;
|
||||
sa2.push_back(-1);
|
||||
height2.push_back(-1);
|
||||
sa2.push_back(sa[1]);
|
||||
height2.push_back(0);
|
||||
int current_shared_length = kInf;
|
||||
for (int i = 2; i <= n; i++) {
|
||||
current_shared_length = min(current_shared_length, height[i]);
|
||||
if (sa[i] < sa2.back()) {
|
||||
sa2.push_back(sa[i]);
|
||||
height2.push_back(current_shared_length);
|
||||
current_shared_length = kInf;
|
||||
}
|
||||
}
|
||||
vector<pair<int, int>> stk;
|
||||
for (int i = sa2.size() - 1; i >= 1; i--) {
|
||||
if (i == sa2.size() - 1) [[unlikely]] {
|
||||
stk.push_back(make_pair(sa2[i], n + 1 - sa2[i]));
|
||||
int L = 1;
|
||||
if (i - 1 >= 1) L = n + 1 - sa2[i - 1] + 1;
|
||||
for (int j = L; j <= n + 1 - sa2[i]; j++) res[j] = sa2[i];
|
||||
continue;
|
||||
}
|
||||
while (stk.size()) {
|
||||
int h = height2[i + 1];
|
||||
if (stk.back().second < h) break;
|
||||
if (stk.size() >= 2 && (stk.end() - 2)->second >= h)
|
||||
stk.pop_back();
|
||||
else {
|
||||
stk.back().second = h;
|
||||
break;
|
||||
}
|
||||
}
|
||||
stk.push_back(make_pair(sa2[i], n + 1 - sa2[i]));
|
||||
int L = 1;
|
||||
if (i - 1 >= 1) L = n + 1 - sa2[i - 1] + 1;
|
||||
for (int j = n + 1 - sa2[i], p = stk.size() - 1; j >= L; j--) {
|
||||
while (p > 0 && stk[p - 1].second >= j) p--;
|
||||
res[j] = stk[p].first;
|
||||
}
|
||||
}
|
||||
write(res[1]);
|
||||
for (int i = 2; i <= n; i++) write(' ', res[i]);
|
||||
write("\n");
|
||||
return 0;
|
||||
}
|
Reference in New Issue
Block a user