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

若如初见. 提交于 2020-01-21 14:24:17

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

题目描述

In graph theory, if an undirected gragh G(V, E) without cycle has n vertices, n − 1 edges and the graph is connected, then G(V, E) is called a tree.
You are given a tree has n vertices, each vertice has a weight. Vertice i’s weight is wiw_i. Henry has q queries, each query has two vertices u, v. He wants to know the xor sum of the weights of all vertices on the shortest path from u to v (contains u,v).

输入描述:

The first line is an integer n(1n105)n (1 ≤ n ≤ 10^5 ), the number of the vertices.
Line 2 has n integers , the ith integer is wi(1wi109)w_i (1 ≤ w_i ≤ 10^9)
, the weight of the vertice i.
Line 3 to line n+1, each line has two integers u, v, means there has an edge between uuand vv (1u,vn)(1 ≤ u, v \leq n).
Line n + 1 is q, means the number of queries.
Next q(1q105)q (1 ≤ q ≤ 10^5 ) lines, each line has two integers u, v (1 ≤ u, v ≤ n) means the beginning and end of
the shortest path henry wants to query.

输出描述:

For each query,output the xor sum of the weights of all vertices on the shortest path from u to v.

示例1

输入

6
1 1 2 3 4 10
1 2
1 3
1 4
2 5
2 6
2
3 6
2 4

输出

8
3

看了题解发现倍增算法这种好东西,自学了一下,挂出来供大伙儿参考,(●’◡’●)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e5+10;
int deep[N];//节点深度
int f[N][20];
int parent[N];
int a[N];
int x[N];
vector<int>G[N];
void DFS(int u,int father){
    f[u][0]=father;
    deep[u]=deep[father]+1;
    for(int v:G[u]){
        if(v==father) continue;
        DFS(v,u);
    }
}

void ST(int n){
    for(int j=1;(1<<j)<=n;j++)
        for(int i=1;i<=n;i++)
            f[i][j]=f[f[i][j-1]][j-1];
}

int lca(int u,int v){
    if(deep[u]<deep[v])
        swap(u,v);
    int h=deep[u]-deep[v];
    for(int i=0;i<20;i++){
        if (h&(1<<i)) u=f[u][i];
    }
    if(u==v) return u;
    for(int i=19;i>=0;i--){
        if(f[u][i]!=f[v][i]){
            u=f[u][i];
            v=f[v][i];
        }
    }
    return f[u][0];
}

void dfs(int u,int father){
    parent[u]=father;
    x[u]=x[father]^a[u];
    for(int v:G[u]){
        if(v==father) continue;
        dfs(v,u);
    }
}

int main()
{
    int n,u,v,q;
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    for(int i=1;i<=n-1;i++){
        cin>>u>>v;
        G[u].push_back(v);
        G[v].push_back(u);
    }
    DFS(1,0);
    dfs(1,0);
    ST(n);
    cin>>q;
    while(q--){
        cin>>u>>v;
        int ancestor=lca(u,v);
        cout<<(x[u]^x[v]^x[ancestor]^x[parent[ancestor]])<<endl;
    }
    return 0;
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!