QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#706844 | #7512. Almost Prefix Concatenation | Deltax | TL | 0ms | 0kb | C++14 | 3.9kb | 2024-11-03 13:39:58 | 2024-11-03 13:40:00 |
answer
#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define mkp make_pair
#define pb push_back
typedef pair <int, int> pii;
inline int read() {
int x = 0, f = 0;
char c = getchar();
while (!isdigit(c)) {if (c == '-') f = 1; c = getchar();}
while (isdigit(c)) x = (x << 1) + (x << 3) + (c & 15), c = getchar();
return f? -x : x;
}
const int MAXN = 1e6;
char s[MAXN + 10], t[MAXN + 10];
namespace SAM {
const int MAXS = MAXN*4 + 10;
vector <int> G[MAXS];
//int ch[MAXS][28];
map <short, int> ch[MAXS];
int len[MAXS], fa[MAXS], last, tot;
int extend(int c) {
int np = ++tot, p = last; last = np;
len[np] = len[p] + 1;
for (; p && ch[p].find(c) == ch[p].end(); p = fa[p]) ch[p][c] = np;
if (ch[p].find(c) == ch[p].end()) {
ch[p][c] = np;
fa[np] = p;
return np;
}
int q = ch[p][c];
if (len[q] > len[p] + 1) {
int nq = ++tot; len[nq] = len[p] + 1; fa[nq] = fa[q];
ch[nq] = ch[q];
//for (int i = 0; i < 26; ++i) ch[nq][i] = ch[q][i];
fa[np] = fa[q] = nq;
for (; ch[p].find(c) != ch[p].end() && ch[p][c] == q; p = fa[p]) ch[p][c] = nq;
}
else fa[np] = q;
return np;
}
//ST :: ST<pii> st;
int siz[MAXS], son[MAXS], top[MAXS], d[MAXS];
void dfs1(int x) {
siz[x] = 1;
for (auto v : G[x]) {
//d[v] = d[x] + 1;
dfs1(v);
siz[x] += siz[v];
if (!son[x] || siz[v] > siz[son[x]])
son[x] = v;
}
}
void dfs2(int x) {
if (son[x]) {
top[son[x]] = top[x];
dfs2(son[x]);
}
for (auto v : G[x])
if (v != son[x]) top[v] = v, dfs2(v);
}
int LCA(int x, int y) {
while (top[x] != top[y]) {
if (d[top[x]] > d[top[y]]) swap(x, y);
y = fa[top[y]];
}
return d[x] < d[y]? x : y;
}
void build() {
for (int i = 0; i <= tot; ++i)
ch[i].clear();
for (int i = 1; i <= tot; ++i)
G[fa[i]].pb(i);
dfs1(0);
dfs2(0);
}
void clear() {
// st.clear();
for (int i = 0; i <= tot + 1; ++i) {
// memset(ch[i], 0, sizeof(ch[i]));
ch[i].clear();
len[i] = fa[i] = 0;
siz[i] = d[i] = son[i] = top[i] = 0;
G[i].clear();
}
last = tot = 0;
}
inline int LCP(int x, int y) {return len[LCA(x, y)];} //front
}
int rm[MAXN + 10];
int pos1[MAXN + 10], pos2[MAXN + 10];
const int Mod = 998244353;
inline int add(int u, int v) {
return (u + v) % Mod;
}
inline int sub(int u, int v) {
return (u + Mod - v) % Mod;
}
int main() {
scanf("%s", s + 1);
scanf("%s", t + 1);
int n = strlen(s + 1);
int m = strlen(t + 1);
for (int i = m; i >= 1; --i)
pos2[i] = SAM::extend(t[i] - 'a');
for (int i = n; i >= 1; --i)
pos1[i] = SAM::extend(s[i] - 'a');
SAM::build();
for (int i = 1; i <= n; ++i) {
rm[i] = SAM::LCP(pos1[i], pos2[1]);
rm[i] += 1 + SAM::LCP(pos1[i + rm[i] + 1], pos2[1 + rm[i] + 1]);
rm[i] = min(rm[i], n - i + 1);
rm[i] = min(rm[i], m);
rm[i] = i + rm[i] - 1;
// cout << rm[i] << " \n"[i == n];
}
static int sf[MAXN + 10][3];
sf[n + 1][0] = 1;
sf[n + 1][1] = 0;
sf[n + 1][2] = 0;
for (int i = n; i >= 1; --i) {
static int val[3];
int r = rm[i] + 1;
int tmp = sub(sf[i + 1][1], sf[r + 1][1]);
val[0] = sub(sf[i + 1][0], sf[r + 1][0]);
val[1] = add(tmp, val[0]);
val[2] = sub(sf[i + 1][2], sf[r + 1][2]);
val[2] = add(add(val[2], (tmp*2)%Mod), val[0]);
for (int j = 0; j <= 2; ++j)
sf[i][j] = add(sf[i + 1][j], val[j]);
}
cout << sub(sf[1][2], sf[2][2]) << endl;
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 0
Time Limit Exceeded
input:
ababaab aba