当前位置: 代码迷 >> 综合 >> 河南理工大学新生挑战赛 C.Xor Path
  详细解决方案

河南理工大学新生挑战赛 C.Xor Path

热度:5   发布时间:2024-01-26 11:09:16.0

题目链接

题意:给你一棵树,每个节点都有权值,有m次查询,问u节点到v节点的最短路径上所有点的异或值。

思路:异或有一个这样的性质就是,异或一个数两次相当于没有异或,所以我们设dp【i】为根节点到i节点的异或值,那么dp【i】=  dp【f【i】】^ w【i】,那么要求的就是答案就等于,dp【u】^   dp【v】^  lca(u,v)。这题卡空间,不能直接用树链刨分,所以就倍增求lca,倍增求lca的步骤就是,如果两个节点的深度不一致,让深度大的节点跳到跟深度小的节点深度相同的祖先,如果相等就返回,如果不相等就同步往上跳。

#include<bits/stdc++.h>
using namespace std;
int n,w[100005],q,dep[100005];
int u,v,cnt;
int d[100005],fa[100005][20];vector<int>G[100005];void dfs(int u,int f){fa[u][0]=f;for(int i=1;i<20;i++) fa[u][i]=fa[fa[u][i-1]][i-1];dep[u]=dep[f]+1;for(auto v : G[u]){if(v==f) continue;d[v]=d[u]^w[v];dfs(v,u);}
}int lca(int x,int y){if(dep[x]<dep[y]) swap(x,y);for(int i=19;i>=0;i--){if(dep[fa[x][i]]>=dep[y]) x=fa[x][i];}if(x==y) return x;for(int i=19;i>=0;i--){if(fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i];}return fa[x][0];
}int main(){scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d",w+i);for(int i=1;i<n;i++){scanf("%d%d",&u,&v);G[u].push_back(v);G[v].push_back(u);}d[1]=w[1];dfs(1,0);scanf("%d",&q);while(q--){scanf("%d%d",&u,&v);printf("%d\n",d[u]^d[v]^w[lca(u,v)]);}return 0;
}

 

  相关解决方案