Problem E. TeaTree
ps:对每个Value都开一个线段树,线段树的叶子节点的值表示的是这个Value的约数,什么意思呢?叶子节点的编号和Value的约数是一一对应的,然后区间维护最大值,是不是非常非常暴力,最后从底向上合并线段树(因为树的每个节点都开了一个线段树),注意要动态开点!!!
官方题解:
inline void upd(int &x, int y) { x < y && (x = y); } const int N = 100005; int n, tot, cnt; int head[N], ans[N], root[N], ls[400 * N], rs[400 * N], sum[400 * N]; struct node { int to, next; } G[N]; vector<int> d[N]; void Inite() { cnt = tot = 0; mem(head, -1); for (int i = 1; i < N; ++i) for (int j = 1; i * j < N; ++j) d[i * j].pb(i); } void addedge(int u, int v) { G[tot].to = v, G[tot].next = head[u], head[u] = tot++; } void Pushup(int rt) { if (ls[rt] && rs[rt]) sum[rt] = max(sum[ls[rt]], sum[rs[rt]]); else if (ls[rt]) sum[rt] = sum[ls[rt]]; else if (rs[rt]) sum[rt] = sum[rs[rt]]; } int Merge(int x, int y, int& res) { if (!x || !y) return x ^ y; if (sum[x] == sum[y]) res = max(res, sum[x]); ls[x] = Merge(ls[x], ls[y], res); rs[x] = Merge(rs[x], rs[y], res); Pushup(x); return x; } void DFS(int u) { ans[u] = -1; for (int i = head[u]; ~i; i = G[i].next) { DFS(G[i].to); root[u] = Merge(root[u], root[G[i].to], ans[u]); } } void Update(int l, int r, int &rt, int pos) { if (!rt) rt = ++cnt; if (l == r) { sum[rt] = pos; return; } int mid = (l + r) >> 1; if (pos <= mid) Update(l, mid, ls[rt], pos); else Update(mid + 1, r, rs[rt], pos); Pushup(rt); } int main() { Inite(); sc(n); Rep(i, 2, n) { int x; sc(x); addedge(x, i); } Rep(i, 1, n) { int x; sc(x); root[i] = 0; rep(j, 0, Size(d[x])) Update(1, N - 1, root[i], d[x][j]); } DFS(1); Rep(i, 1, n) pr(ans[i]); return 0; }