QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#276349 | #7188. Aho-Corasick Automaton | PetroTarnavskyi# | WA | 3ms | 26304kb | C++17 | 3.1kb | 2023-12-05 20:14:58 | 2023-12-05 20:14:58 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
#define FOR(i, a, b) for(int i = (a); i < (b); i++)
#define RFOR(i, b, a) for(int i = (b) - 1; i >= (a); i--)
#define SZ(a) (int)a.size()
#define ALL(a) a.begin(), a.end()
#define PB push_back
#define MP make_pair
#define F first
#define S second
typedef long long LL;
typedef vector<int> VI;
typedef pair<int, int> PII;
typedef double db;
const LL mod1 = 1'000'000'007;
const LL mod2 = 1'000'000'009;
const LL mod = mod1 * mod2;
LL add(LL a, LL b)
{
return a + b < mod ? a + b : a + b - mod;
}
LL sub(LL a, LL b)
{
return a - b >= 0 ? a - b : a - b + mod;
}
LL mult(LL a, LL b)
{
return (__int128)a * b % mod;
}
const int N = 200'447;
const int LOG = 18;
VI vec[N];
LL hs[N];
int h[N];
int up[LOG][N];
struct Node
{
int p;
int c;
unordered_map<int, int> g;
unordered_map<int, int> nxt;
int link;
void init()
{
c = -1;
p = -1;
link = -1;
}
};
struct AC
{
vector<Node> a;
int sz;
void init(int n)
{
a.resize(n);
a[0].init();
sz = 1;
}
int go(int v, int c)
{
if (a[v].g.count(c) == 1)
return a[v].g[c];
if (a[v].nxt.count(c) == 1)
a[v].g[c] = a[v].nxt[c];
else if (v != 0)
a[v].g[c] = go(getLink(v), c);
else
a[v].g[c] = 0;
return a[v].g[c];
}
int getLink(int v)
{
if (a[v].link != -1)
return a[v].link;
if (v == 0 || a[v].p == 0)
return 0;
return a[v].link=go(getLink(a[v].p), a[v].c);
}
} ac;
const int MAGIC = 777;
int x = 7474747;
LL pw[N];
void dfs(int v, int c, int H)
{
h[v] = H;
hs[v] = add(mult(hs[up[0][v]], x), c);
FOR (i, 1, LOG)
{
up[i][v] = up[i - 1][up[i - 1][v]];
}
for (auto [C, to] : ac.a[v].nxt)
{
dfs(to, C, H + 1);
}
}
int f(int v, int c)
{
int ans = 0;
for (auto u : vec[c])
{
if (h[u] >= h[v])
continue;
int p = v;
RFOR (i, LOG, 0)
{
if (h[v] - h[up[i][p]] <= h[u])
p = up[i][p];
}
assert(p != 0);
p = up[0][p];
LL hsh = sub(hs[v], mult(hs[p], pw[h[u]]));
if (hsh == hs[u] && h[u] > h[ans])
{
ans = u;
break;
}
}
ac.a[v].link = ans;
return ans;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout << fixed << setprecision(15);
pw[0] = 1;
FOR (i, 1, N)
pw[i] = mult(pw[i - 1], x);
int n;
cin >> n;
VI cnt(n);
VI idx(n);
iota(ALL(idx), 0);
ac.init(n + 1);
FOR(i, 0, n + 1)
ac.a[i].init();
VI p(n), c(n);
FOR(i, 0, n)
cin >> p[i];
FOR(i, 0, n)
{
cin >> c[i];
c[i]--;
cnt[c[i]]++;
}
sort(ALL(idx), [&](int i, int j)
{
return cnt[i] > cnt[j];
});
VI a(n);
FOR (i, 0, n)
a[idx[i]] = i;
FOR(i, 0, n)
{
ac.a[p[i]].nxt[c[i]] = i + 1;
up[0][i + 1] = p[i];
ac.a[i + 1].p = p[i];
ac.a[i + 1].c = c[i];
if (cnt[c[i]] < MAGIC)
vec[c[i]].PB(i + 1);
}
FOR (i, 0, n)
{
sort(ALL(vec[i]), [&](int u, int v)
{
return h[u] > h[v];
});
}
dfs(0, 0, 0);
FOR(i, 1, n + 1)
{
if(i > 1)
cout << " ";
if (cnt[c[i - 1]] < MAGIC)
{
cout << f(i, c[i - 1]);
}
else
cout << ac.getLink(i);
}
cout << "\n";
return 0;
}
详细
Test #1:
score: 100
Accepted
time: 0ms
memory: 26040kb
input:
2 0 0 1 2
output:
0 0
result:
ok 2 number(s): "0 0"
Test #2:
score: 0
Accepted
time: 0ms
memory: 24288kb
input:
2 0 1 1 1
output:
0 1
result:
ok 2 number(s): "0 1"
Test #3:
score: 0
Accepted
time: 0ms
memory: 26304kb
input:
1 0 1
output:
0
result:
ok 1 number(s): "0"
Test #4:
score: -100
Wrong Answer
time: 3ms
memory: 24436kb
input:
50 0 1 1 1 0 0 4 4 3 7 1 11 1 11 2 15 13 11 4 11 5 7 22 17 4 19 19 26 19 27 3 17 9 4 14 8 15 33 33 33 9 40 24 18 5 28 10 1 47 25 20 20 31 1 43 3 3 21 3 3 3 22 43 3 1 20 3 43 43 20 3 20 1 3 20 20 3 1 43 3 20 20 20 29 3 3 3 3 20 1 3 3 3 3 20 3 3 25 3 1
output:
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 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:
wrong answer 2nd numbers differ - expected: '1', found: '0'