社区讨论
求条(玄关+满足你三项要求)
题目总版参与者 3已保存回复 7
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 7 条
- 当前快照
- 1 份
- 快照标识符
- @mli30u29
- 此快照首次捕获于
- 2026/02/11 21:45 上周
- 此快照最后确认于
- 2026/02/11 23:05 上周
rt,不涉及金钱,我力所能及的都可以。
求求了qwq
CPP#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
int n, m;
vector <int> s[N];
int tot, dfn[N];
inline bool cmp (int u, int v) {return dfn[u] < dfn[v];}
struct AC {
map <int, int> mp;
int sz[N], dep[N], f[N][26];
int fail[N], stk[N];
struct node {
map <int, int> son;
int id;
} tr[N];
vector <int> g[N];
struct BIT {
int bit[N];
inline void update (int x, int vl) {
for (; x <= tot; x += (x & -x))
bit[x] += vl;
}
inline int sum (int x) {
int ret = 0;
for (; x > 0; x -= (x & -x))
ret += bit[x];
return ret;
}
inline int query (int l, int r) {return sum (r) - sum (l - 1);}
inline void clear () {memset (bit, 0, sizeof (bit));}
} c;
inline void insert (int vl) {
int p = 0, len;
cin >> len;
for (int i = 1; i <= len; i++) {
int dir;
cin >> dir;
if (!tr[p].son[dir])
tr[p].son[dir] = ++tot;
p = tr[p].son[dir];
}
if (!tr[p].id) tr[p].id = vl;
mp[vl] = tr[p].id;
}
int get (int u, int dir) {
if (tr[u].son.count (dir))
return tr[u].son[dir];
if (!u) return u;
return tr[u].son[dir] = get (fail[u], dir);
}
inline void dfs (int u, int fa) {
sz[u] = 1;
dep[u] = dep[fa] + 1;
f[u][0] = fa;
dfn[u] = ++tot;
for (int v : g[u]) {
dfs (v, u);
sz[u] += sz[v];
}
}
inline int LCA (int u, int v) {
if (dep[u] < dep[v]) swap (u, v);
for (int i = 25; i >= 0; i--)
if (dep[f[u][i]] >= dep[v])
u = f[u][i];
if (u == v) return u;
for (int i = 25; i >= 0; i--)
if (f[u][i] != f[v][i])
u = f[u][i], v = f[v][i];
return f[u][0];
}
inline void init () {
for (int j = 1; (1 << j) <= tot; j++)
for (int i = 1; i <= tot; i++)
f[i][j] = f[f[i][j - 1]][j - 1];
}
inline void build () {
queue <int> q;
for (auto p : tr[0].son) {
int v = p.second;
q.push (v);
g[0].push_back (v);
}
while (!q.empty ()) {
int u = q.front ();
q.pop ();
for (auto p : tr[u].son) {
int dir = p.first;
int v = p.second;
q.push (v);
fail[v] = get (fail[u], dir);
g[fail[v]].push_back (v);
}
}
tot = 0;
dfs (0, 0);
init ();
}
inline void solve1 () {
c.clear ();
for (int i = 1; i <= n; i++) {
int p = 0, top = 0;
for (auto ch : s[i]) {
p = get (p, ch);
stk[++top] = p;
}
sort (stk + 1, stk + top + 1, cmp);
top = unique (stk + 1, stk + top + 1) - stk - 1;
for (int j = 1; j <= top; j++) {
c.update (dfn[stk[j]], 1);
c.update (dfn[LCA (stk[j], stk[j - 1])], -1);
}
}
for (int i = 1; i <= m; i++) {
int l = dfn[mp[i]];
int r = l + sz[mp[i]] - 1;
cout << c.query (l, r) << "\n";
}
}
inline void solve2 () {
c.clear ();
for (int i = 1; i <= m; i++) {
c.update (dfn[mp[i]], 1);
c.update (dfn[mp[i]] + sz[mp[i]] - 1, -1);
}
for (int i = 1; i <= n; i++) {
int p = 0, top = 0, ans = 0;
for (auto ch : s[i]) {
p = get (p, ch);
stk[++top] = p;
}
sort (stk + 1, stk + top + 1, cmp);
top = unique (stk + 1, stk + top + 1) - stk - 1;
for (int j = 1; j <= top; j++) {
ans += c.sum (dfn[stk[j]]);
ans -= c.sum (dfn[LCA (stk[j], stk[j - 1])]);
}
cout << ans << " ";
}
}
} ac;
int main () {
ios :: sync_with_stdio (0);
cin.tie (0), cout.tie (0);
cin >> n >> m;
for (int i = 1; i <= n; i++) {
int len;
cin >> len;
for (int j = 1; j <= len; j++) {
int c;
cin >> c;
s[i].push_back (c);
}
s[i].push_back (-1);
cin >> len;
for (int j = 1; j <= len; j++) {
int c;
cin >> c;
s[i].push_back (c);
}
}
for (int i = 1; i <= m; i++)
ac.insert (i);
ac.build ();
ac.solve1 ();
ac.solve2 ();
return 0;
}
回复
共 7 条回复,欢迎继续交流。
正在加载回复...