• Xor Path 牛客,HPU--C--LCA


    题解:

    题目要求求出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<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const ll N=1E5+7;
    vector<ll >ve[N];
    ll arr[N];
    bool pre[N];
    ll fa[N];
    ll dp[N];
    ll bits[N];
    ll depth[N];
    ll father[N][30];
    void dfs1(ll x,ll y){//y是x的父亲
        fa[x]=y;
        dp[x]=dp[y]^arr[x];
        for(ll i=0;i<ve[x].size();i++){
            ll c=ve[x][i];
            if(c!=y) {
                dfs1(c,x);
            }
        }
    }
    void bt()
    {
        bits[0]=1;
        for(ll i=1;i<=29;i++) bits[i]=bits[i-1]<<1;
    }
    void dfs(ll x,ll y){//x是y的儿子节点
        depth[x]=depth[y]+1;
        father[x][0]=y;
        for(ll i=1;i<=29;i++) father[x][i]=father[father[x][i-1]][i-1];
        for(ll i=0;i<ve[x].size();i++){
            ll c=ve[x][i];
            if(c!=y) {
                dfs(c,x);
            }
        }
    }
    ll lca(ll x,ll y){//设x比y深
        if(depth[x]<depth[y]) swap(x,y);
        ll dif=depth[x]-depth[y];
        for(ll i=29;i>=0;i--){
            if(bits[i]<=dif){
                dif-=bits[i];
                x=father[x][i];
            }
        }
        if(x==y) return x;
        for(ll i=29;i>=0;i--){
            if(depth[x]>=bits[i]&&father[x][i]!=father[y][i]){
                x=father[x][i];
                y=father[y][i];
            }
        }
        return father[x][0];
    
    } 
    int main(){
        ll n;
        cin>>n;
        for(ll i=1;i<=n;i++) cin>>arr[i];
        ll x,y;
        for(ll i=1;i<n;i++){
            cin>>x>>y;
            pre[y]=1;
            ve[x].push_back(y);
            ve[y].push_back(x);
        }
        bt();
        dfs1(1,0);
        dfs(1,0);
        ll q;
        cin>>q;
        for(ll i=1;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 0;
    }
  • 相关阅读:
    SQL 索引
    SQL 存储
    C#编程中的66个好习惯,你有多少个?
    Delphi中如何让窗口最小化至系统托盘
    浅谈 堆和堆栈
    C#编程中的66个好习惯
    用ADO连接oracle的步骤
    如何卸载ocx包
    数据库中,Decimal数据类型
    [转载]内存区划分、内存分配、常量存储区、堆、栈、自由存储区、全局区
  • 原文地址:https://www.cnblogs.com/Accepting/p/12239384.html
Copyright © 2020-2023  润新知