题解:
题目要求求出u和v两点在最短路径上的异或和。怎么确定最短路径呢?,就是U到LCA(u,v)的路径加上V到LCA(u,v)。根据异或的性质,如k^a^a=k,即异或一个值两边等于原数值。
所以维护一个数组dp[i]指的是根节点s到点i的异或和,所以答案应该是dp[u]^dp[v]^dp[lca[u,v]]^arr[lca[u,v]]其中arr是每个点的weight.
code:
#include
using namespace std;
typedef long long ll;
const ll N=1E5+;
vector
ll arr\[N\];
bool pre\[N\];
ll fa\[N\];
ll dp\[N\];
ll bits\[N\];
ll depth\[N\];
ll father\[N\]\[\];
void dfs1(ll x,ll y){//y是x的父亲
fa\[x\]=y;
dp\[x\]=dp\[y\]^arr\[x\];
for(ll i=;i
if(bits[i]<=dif){
dif-=bits[i];
x=father[x][i];
}
}
if(x==y) return x;
for(ll i=;i>=;i--){
if(depth[x]>=bits[i]&&father[x][i]!=father[y][i]){
x=father[x][i];
y=father[y][i];
}
}
return father[x][];
}
int main(){
ll n;
cin>>n;
for(ll i=;i<=n;i++) cin>>arr[i];
ll x,y;
for(ll i=;i
pre[y]=;
ve[x].push_back(y);
ve[y].push_back(x);
}
bt();
dfs1(,);
dfs(,);
ll q;
cin>>q;
for(ll i=;i<=q;i++){
ll x,y;
cin>>x>>y;
ll k=dp[x]^dp[y];
ll a=lca(x,y);
k=k^arr[a];
cout<<k<<endl;
}
return ;
}
手机扫一扫
移动阅读更方便
你可能感兴趣的文章