Dis(代码源打卡day.3)

这篇博客介绍了如何解决一道关于树上两点间简单路径权值的亦或和查询问题。通过DFS计算节点的前缀和,并利用LCA(最近公共祖先)算法,可以高效地求解任意两点间的权值亦或和。代码实现中涉及到了树的遍历、前缀和计算以及LCA查找等数据结构和算法知识。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

随便说点

今天代码源大放水就出了个lcalcalca+前缀和板子题,可惜lcalcalca板子记错了,wawawa了好久。

题意

有一棵树,上面有很多个节点,每个节点都有一个对应的权值,现在有qqq次询问,问任意两点之间简单路径的权值亦或和。

题解

其实很简单,先dfsdfsdfs求前缀和,然后将询问的两点的前缀和亦或因为根节点到公共祖先的权值会被亦或两次而抵消所以我们只要再找一个公共祖先就行了。lcalcalca找到两点公共祖先,亦或上公共祖先的权值直接ACACAC。(直接ACACAC的前提是你没记错lcalcalca的板子)

const int N=2e5+10;
vector<vector<int>> g;
int f[N][30],d[N],a[N],w[N],n,m;
void dfs(int fa,int x){
    w[x]=a[x]^w[fa];
    f[x][0]=fa;d[x]=d[fa]+1;
    for(int i=1;i<=25;i++) f[x][i]=f[f[x][i-1]][i-1];
    for(auto v:g[x]){if(v==fa) continue;dfs(x,v);}
    return ;
}
int lca(int x,int y){
    for(int i=25;i>=0;i--) if(d[f[x][i]]>=d[y]) x=f[x][i];
    for(int i=25;i>=0;i--) if(d[f[y][i]]>=d[x]) y=f[y][i];
    if(x==y) return x;
    for(int i=25;i>=0;i--) if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];
    return f[x][0];
}
void MAIN(){
    cin>>n>>m;
    g.resize(n+1);
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=1,u,v;i<n&&cin>>u>>v;i++) g[u].push_back(v),g[v].push_back(u);
    dfs(0,1);
    int x,y;
    while(cin>>x>>y){
        int anc=lca(x,y);
        cout<<(w[x]^w[y]^a[anc])<<endl;
    }
    return ;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值