题解 P5287 【[HNOI2019]JOJO】
数组不清空,爆0两行泪
首先你发现这个串是由一堆二元组
这个显然可以有一个
很显然那个2的可持久化操作我们需要离线建棵树然后dfs(其实在线在这棵树上做做应该也是可以的……),我们就考虑当前点到根的串就行了。
既然那中间的二元组需要严格的匹配,那我们不妨把这个求一个
这里要特别注意的是,由于我们现在是在树上跑
(接下来为了方便描述,我们就称这个串的fail树为每个二元组的位置以
然后我们考虑添加一个二元组
(其中黑色部分是这条fail链,红色的是一个长度为
我们对
另外我们需要特判像下面这样的这种情况:
考虑最后一段
上代码~
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#define ll long long
#define p 998244353
#define up(_o) data[_o] = (data[lef[_o]] + data[rgh[_o]]) % p
using namespace std;
namespace ywy {
inline int get() {
int n = 0;
char c;
while ((c = getchar()) || 23333) {
if (c >= '0' && c <= '9')
break;
if (c == '-')
goto s;
}
n = c - '0';
while ((c = getchar()) || 23333) {
if (c >= '0' && c <= '9')
n = n * 10 + c - '0';
else
return (n);
}
s:
while ((c = getchar()) || 23333) {
if (c >= '0' && c <= '9')
n = n * 10 - c + '0';
else
return (n);
}
}
inline char cget() {
char c;
while ((c = getchar()) || 23333)
if (c >= 'a' && c <= 'z')
return (c);
}
typedef struct _b {
int dest;
int nxt;
int x;
int c;
} bian;
bian memchi[1000001], stk[100011];
int gn = 1, heads[200001], f[200011][26], nxt[200011][26];
inline void add(int s, int t, int x, int c) {
memchi[gn].dest = t;
memchi[gn].nxt = heads[s];
memchi[gn].x = x;
memchi[gn].c = c;
heads[s] = gn;
gn++;
}
int lef[20000001], rgh[20000001];
int data[20000001], anss[200001], changes[20000001];
int id[200001], gseg = 1;
int set(int rl, int rr, int l, int r, int tree, int x, int chg) {
int me = gseg;
gseg++;
if (rl == l && rr == r) {
changes[me] = x;
data[me] = (x * (ll)(r - l + 1)) % p;
return (me);
}
int mid = (l + r) >> 1;
if (changes[tree])
chg = changes[tree];
if (rl > mid) {
if (chg) {
lef[me] = gseg;
gseg++;
changes[lef[me]] = chg;
data[lef[me]] = (chg * (mid - l + 1)) % p;
rgh[me] = set(rl, rr, mid + 1, r, rgh[tree], x, chg);
} else
lef[me] = lef[tree], rgh[me] = set(rl, rr, mid + 1, r, rgh[tree], x, 0);
} else {
if (rr <= mid) {
if (chg) {
rgh[me] = gseg;
gseg++;
changes[rgh[me]] = chg;
data[rgh[me]] = (chg * (ll)(r - mid)) % p;
lef[me] = set(rl, rr, l, mid, lef[tree], x, chg);
} else
rgh[me] = rgh[tree], lef[me] = set(rl, rr, l, mid, lef[tree], x, 0);
} else {
lef[me] = set(rl, mid, l, mid, lef[tree], x, chg);
rgh[me] = set(mid + 1, rr, mid + 1, r, rgh[tree], x, chg);
}
}
up(me);
return (me);
}
int query(int rl, int rr, int l, int r, int tree) {
if (!tree)
return (0);
int mid = (l + r) >> 1;
if (changes[tree])
return ((changes[tree] * (ll)(rr - rl + 1)) % p);
if (rl == l && rr == r)
return (data[tree]);
if (rl > mid)
return (query(rl, rr, mid + 1, r, rgh[tree]));
if (rr <= mid)
return (query(rl, rr, l, mid, lef[tree]));
return ((query(rl, mid, l, mid, lef[tree]) + query(mid + 1, rr, mid + 1, r, rgh[tree])) % p);
}
int sp = 1, fail[200001], mx[200001][26];
inline ll dft(ll n) { return (((n * (n + 1)) >> 1) % p); }
void dfs(int pt, int deep) {
for (register int i = heads[pt]; i; i = memchi[i].nxt) {
if (pt) {
for (register int j = 0; j < 26; j++)
mx[pt][j] = mx[fail[pt]][j], f[pt][j] = f[fail[pt]][j], nxt[pt][j] = nxt[fail[pt]][j];
} else {
for (register int j = 0; j < 26; j++) mx[pt][j] = 0, f[pt][j] = 0, nxt[pt][j] = 0;
}
if (pt == 0)
stk[1] = memchi[i];
fail[memchi[i].dest] = query(memchi[i].x, memchi[i].x, 1, 10000, nxt[pt][memchi[i].c]);
if (pt == 0) {
anss[memchi[i].dest] = dft(memchi[i].x - 1);
} else {
if (!fail[pt]) {
if (memchi[i].c != stk[1].c)
anss[memchi[i].dest] = anss[pt];
else
anss[memchi[i].dest] =
(anss[pt] + dft(min(memchi[i].x, mx[pt][memchi[i].c])) +
(ll)(memchi[i].x - min(memchi[i].x, mx[pt][memchi[i].c])) * mx[pt][memchi[i].c]) %
p;
} else {
anss[memchi[i].dest] = (anss[pt] + dft(min(memchi[i].x, mx[pt][memchi[i].c])) +
(ll)query(1, memchi[i].x, 1, 10000, f[pt][memchi[i].c])) %
p;
if (memchi[i].x > mx[pt][memchi[i].c] && memchi[i].c == stk[1].c) {
anss[memchi[i].dest] =
(anss[memchi[i].dest] + stk[1].x * (ll)(memchi[i].x - mx[pt][memchi[i].c])) % p;
}
}
}
f[pt][memchi[i].c] = set(1, memchi[i].x, 1, 10000, f[fail[pt]][memchi[i].c], deep, 0);
if (pt == 0) {
nxt[pt][memchi[i].c] =
set(memchi[i].x, 10000, 1, 10000, nxt[fail[pt]][memchi[i].c], memchi[i].dest, 0);
} else
nxt[pt][memchi[i].c] =
set(memchi[i].x, memchi[i].x, 1, 10000, nxt[fail[pt]][memchi[i].c], memchi[i].dest, 0);
mx[pt][memchi[i].c] = max(mx[fail[pt]][memchi[i].c], memchi[i].x);
dfs(memchi[i].dest, deep + memchi[i].x);
}
}
void ywymain() {
int n = get();
int cur = 0, gpt = 1;
for (register int i = 1; i <= n; i++) {
int op = get();
if (op == 2)
cur = id[get()];
else {
int x = get();
char c = cget();
add(cur, gpt, x, c - 'a');
cur = gpt;
gpt++;
}
id[i] = cur;
}
dfs(0, 0);
for (register int i = 1; i <= n; i++) printf("%d\n", anss[id[i]]);
}
}
int main() {
ywy::ywymain();
return (0);
}