QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#236659 | #7513. Palindromic Beads | alpha1022 | WA | 19ms | 254500kb | C++14 | 4.3kb | 2023-11-04 09:36:23 | 2023-11-04 09:36:24 |
Judging History
answer
#include <bits/stdc++.h>
using namespace std;
const int inf = 0x3f3f3f3f;
const int N = 2e5;
const int LG = 20;
int n;
int a[N + 5];
pair<int, int> pos[N + 5];
vector<int> e[N + 5];
int fa[N + 5], anc[N + 5][LG], dep[N + 5], siz[N + 5], id[N + 5];
int f[N + 5];
void dfs1(int u) {
static int tot = 0;
id[u] = ++tot, siz[u] = 1, anc[u][0] = fa[u];
for (int k = 1; k < LG; ++k) anc[u][k] = anc[anc[u][k - 1]][k - 1];
for (int v: e[u])
if (v != fa[u])
fa[v] = u, dep[v] = dep[u] + 1, dfs1(v), siz[u] += siz[v];
}
int query(int u, int v) {
for (int k = LG - 1; k >= 0; --k)
if (dep[anc[u][k]] > dep[v]) u = anc[u][k];
return u;
}
struct SegmentTree {
#define ls (u << 1)
#define rs (ls | 1)
int seg[N * 4 + 5];
void build(int u, int tl, int tr) {
seg[u] = -inf;
if (tl == tr) return ;
int mid = (tl + tr) >> 1;
build(ls, tl, mid), build(rs, mid + 1, tr);
}
void pushUp(int u) { seg[u] = max(seg[ls], seg[rs]); }
void insert(int x, int k, int u, int tl, int tr) {
if (tl == tr) { seg[u] = k; return ; }
int mid = (tl + tr) >> 1;
if (x <= mid) insert(x, k, ls, tl, mid);
else insert(x, k, rs, mid + 1, tr);
pushUp(u);
}
int query(int l, int u, int tl, int tr) {
if (l <= tl) return seg[u];
int mid = (tl + tr) >> 1;
int ret = query(l, rs, mid + 1, tr);
if (l <= mid) ret = max(ret, query(l, ls, tl, mid));
return ret;
}
#undef ls
#undef rs
} seg;
struct TreeOfTree {
struct segnode { int val = -inf, ls, rs; } seg[N * 100 + 5];
void update(int l, int r, int k, int &u, int tl, int tr) {
if (l > r) return ;
static int tot = 0;
if (!u) u = ++tot;
if (l <= tl && tr <= r) { seg[u].val = max(seg[u].val, k); return ; }
int mid = (tl + tr) >> 1;
if (l <= mid) update(l, r, k, seg[u].ls, tl, mid);
if (r > mid) update(l, r, k, seg[u].rs, mid + 1, tr);
}
int query(int x, int u, int tl, int tr) {
if (tl == tr) return seg[u].val;
int mid = (tl + tr) >> 1;
return max(seg[u].val, x <= mid ? query(x, seg[u].ls, tl, mid) : query(x, seg[u].rs, mid + 1, tr));
}
#define ls (u << 1)
#define rs (ls | 1)
int rt[N * 4 + 5];
void update(int l, int r, int x, int y, int k, int u, int tl, int tr) {
if (l > r || x > y) return ;
if (l <= tl && tr <= r) { update(x, y, k, rt[u], 1, n); return ; }
int mid = (tl + tr) >> 1;
if (l <= mid) update(l, r, x, y, k, ls, tl, mid);
if (r > mid) update(l, r, x, y, k, rs, mid + 1, tr);
}
int query(int x, int y, int u, int tl, int tr) {
if (tl == tr) return query(y, rt[u], 1, n);
int mid = (tl + tr) >> 1;
return x <= mid ? query(x, y, ls, tl, mid) : query(x, y, rs, mid + 1, tr);
}
#undef ls
#undef rs
} tree;
int up[N + 5];
void dfs2(int u) {
if (up[u]) {
f[a[u]] = 2 + (dep[up[u]] < dep[u] - 1);
seg.insert(dep[up[u]], f[a[u]] = max(f[a[u]], seg.query(dep[up[u]], 1, 0, n - 1) + 2), 1, 0, n - 1);
int v = query(u, up[u]);
tree.update(1, id[v] - 1, id[u], id[u] + siz[u] - 1, f[a[u]], 1, 1, n), tree.update(id[u], id[u] + siz[u] - 1, id[v] + siz[v], f[a[u]], n, 1, 1, n);
}
for (int v: e[u])
if (v != fa[u])
dfs2(v);
if (up[u]) seg.insert(dep[up[u]], -inf, 1, 0, n - 1);
}
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; ++i) pos[i] = {n + 1, n + 1};
for (int i = 1; i <= n; ++i) {
int x; scanf("%d", &x), a[i] = x;
if (pos[x].first <= n) pos[x].second = i;
else pos[x].first = i;
}
for (int i = 2; i <= n; ++i) { int u, v; scanf("%d%d", &u, &v), e[u].push_back(v), e[v].push_back(u); }
dfs1(1);
for (int i = 1; i <= n; ++i) {
auto &[u, v] = pos[i];
if (u <= n && v <= n && id[u] < id[v]) swap(u, v);
}
sort(pos + 1, pos + n + 1);
for (int i = 1; i <= n; ++i) {
auto [u, v] = pos[i];
if (u > n || v > n) continue;
if (id[u] >= id[v] && id[u] < id[v] + siz[v]) a[u] = i, up[u] = v;
}
seg.build(1, 0, n - 1), dfs2(1);
for (int i = 1; i <= n; ++i) {
auto [u, v] = pos[i];
if (u > n || v > n) continue;
if (id[u] >= id[v] && id[u] < id[v] + siz[v]) continue;
tree.update(id[v], id[v] + siz[v] - 1, id[u], id[u] + siz[u] - 1, f[i] = max(3, tree.query(id[v], id[u], 1, 1, n) + 2), 1, 1, n);
}
printf("%d\n", *max_element(f + 1, f + n + 1));
}
详细
Test #1:
score: 100
Accepted
time: 12ms
memory: 253676kb
input:
4 1 1 2 2 1 2 2 3 2 4
output:
3
result:
ok single line: '3'
Test #2:
score: 0
Accepted
time: 19ms
memory: 253752kb
input:
5 1 3 2 2 1 1 2 2 3 3 4 4 5
output:
4
result:
ok single line: '4'
Test #3:
score: 0
Accepted
time: 12ms
memory: 253956kb
input:
6 1 1 2 2 3 3 1 2 2 3 3 4 4 5 5 6
output:
2
result:
ok single line: '2'
Test #4:
score: -100
Wrong Answer
time: 4ms
memory: 254500kb
input:
6 1 2 3 4 5 6 1 2 2 3 3 4 4 5 5 6
output:
0
result:
wrong answer 1st lines differ - expected: '1', found: '0'