peiwenjun's blog 没有知识的荒原

P8511 [Ynoi Easy Round 2021] TEST_68 题解

题目描述

给定一棵 \(n\) 个节点的有根树,根节点为 \(1\) 号点,点有点权 \(a_i\)

对每个点 \(x\) ,求其子树外 \(a_i\oplus a_j\) 的最大值,若找不出两个点,则答案为 \(0\)

数据范围

  • \(1\le n\le 5\cdot 10^5,0\le a_i\le 10^{18},1\le fa_i\le i-1\)

时间限制 \(\texttt{3s}\) ,空间限制 \(\texttt{512MB}\)

分析

集合的最大异或值是 \(\texttt{trie}\) 上的一个经典问题,在插入每个数之前查询当前数和已经插入的数的最大异或值即可。

观察样例可知对于大量的节点答案是一样的,具体的,假设全局最大异或值为 \(a_x\oplus a_y\) ,那么对于除了 \(x\to y\) 路径上的所有点,答案均为 \(a_x\oplus a_y\)

接下来只需处理 \(x,y\) 分别跳到 \(\texttt{lca(x,y)}\) 路径上所有点的答案。

注意到 \(\overline{\texttt{subtree}(fa_u)}\subseteq\overline{\texttt{subtree}(u)}\) ,因此可以把 \(\texttt{lca(x,y)}\) 放宽到根节点然后自顶向下更新。计算 \(u\) 点答案时可以先继承 \(fa_u\) 的答案,然后将 \(fa_u\) 其他子树中的点加入 \(\texttt{trie}\) 即可。

时间复杂度 \(\mathcal O(n\log n)\)

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=5e5+5,maxm=3e7+5;
int n,x,y,z,tot;
int fa[maxn];
int ch[maxm][2],id[maxm];
ll tmp,w[maxn],res[maxn];
vector<int> g[maxn];
void query(int v)
{
    int p=0;
    for(int i=59;i>=0;i--)
    {
        int c=w[v]>>i&1;
        if(ch[p][c^1]) p=ch[p][c^1];
        else p=ch[p][c];
    }
    if(id[p]&&(w[v]^w[id[p]])>tmp) tmp=w[v]^w[id[p]],x=v,y=id[p];
}
void insert(int v)
{
    int p=0;
    for(int i=59;i>=0;i--)
    {
        int c=w[v]>>i&1;
        if(!ch[p][c]) ch[p][c]=++tot;
        p=ch[p][c];
    }
    id[p]=v;
}
void insert_tree(int u,int lim)
{
    query(u),insert(u);
    for(auto v:g[u]) if(v!=lim) insert_tree(v,lim);
}
void work(int x)
{
    memset(ch,tot=tmp=0,sizeof(ch));
    vector<int> vec;
    for(int i=x;i>1;i=fa[i]) vec.push_back(i);
    reverse(vec.begin(),vec.end());
    for(auto u:vec) insert_tree(fa[u],u),res[u]=tmp;
}
int main()
{
    scanf("%d",&n);
    for(int i=2;i<=n;i++) scanf("%d",&fa[i]),g[fa[i]].push_back(i);
    for(int i=1;i<=n;i++) scanf("%lld",&w[i]);
    for(int i=1;i<=n;i++) query(i),insert(i);
    for(int i=2;i<=n;i++) res[i]=tmp;
    z=y,work(x),work(z);///调用 work 函数时会覆盖 x 和 y 的值
    for(int i=1;i<=n;i++) printf("%lld\n",res[i]);
    return 0;
}

posted on 2025-08-25 19:06  peiwenjun  阅读(33)  评论(0)    收藏  举报

导航