zoukankan      html  css  js  c++  java
  • XOR path|LCA最近公共祖先,树链异或和

    题目描述

    补题记录

    思路:DFS计算从根节点到每个节点的异或和,同时计算倍增。
    然后利用倍增可以实现O(logn)的查询。

    #include<bits/stdc++.h>
    using namespace std;
    
    /*
    思路: 
    	DFS计算从根节点到每个节点的异或和,同时计算倍增。
    	然后利用倍增可以实现O(logn)的查询。
    */ 
    
    /*
    小结: 
    	学会了树上异或和的lca优化方法、还需要熟悉和理解lca原理 
    */ 
    
    const int N = 1e6+100;
    vector<int> G[N];
    int pre[N],a[N],par[N];
    long long bit[30];
    int f[N][30];
    int depth[N];
    
    //初始化 
    void init(){
    	bit[0]=1;
    	for(int i=1;i<=29;i++) bit[i]=(bit[i-1]<<1);
    }
    
    //倍增
    void dfs(int u,int par){
    	depth[u]=depth[par]+1;
    	f[u][0]=par;
    	for(int i=1;bit[i]<=depth[u];i++) f[u][i]=f[f[u][i-1]][i-1];
    	for(int v:G[u]){
    		if(v!=par) dfs(v,u);
    	}
    }
    
    //lca
    int lca(int x,int y){
    	if(depth[x]<depth[y]) swap(x,y);
    	for(int i=29;i>=0;i--){
    		if(depth[x]-depth[y]>=bit[i]){
    			x=f[x][i];
    		}
    	}
    	if(x==y) return x;
    	for(int i=29;i>=0;i--){
    		if(depth[x]>=(1<<i)&&f[x][i]!=f[y][i]){
    			x=f[x][i];
    			y=f[y][i];
    		}
    	}
    	return f[x][0];
    }
    
    //从根节点1出发 求每个点到根节点的路径异或和 
    void DFS1(int u,int fa){
        par[u]=fa;
        pre[u]=pre[fa]^a[u];
        for(int v:G[u]){
            if(v==fa) continue;
            DFS1(v,u);
        }
    }
    
    int main(){
        int n,u,v,q;
        cin>>n;
        init();
        //建图 邻接表 
        for(int i=1;i<=n;i++) cin>>a[i];
        for(int i=0;i<=n;i++) G[i].clear();
        for(int i=1;i<=n-1;i++){
            cin>>u>>v;
            G[u].push_back(v);
            G[v].push_back(u);
        }
        //lca
        dfs(1,0);
        //计算从根节点到每个结点的异或和 
        DFS1(1,0);
        int x,y;
        cin>>q;
        while(q--){
            cin>>x>>y;
            int c=lca(x,y); //lca求出最近公共祖先 
            int f=par[c]; //求出最近公共祖先的父节点  这里再求一次父节点的原因是: 消除祖先的父节点到根节点这段路径(异或了2次)的异或 
            cout<<(pre[x]^pre[f]^pre[c]^pre[y])<<endl; //画图理解 树链上异或两次就等于没有异或  
        }
        return 0;
    }
    
    
    
  • 相关阅读:
    configuring express for ejs
    if else in EJS
    nodegroupchat exercise
    heap&stack 区别
    如何构建积木式Web应用(引自微软CSDN )
    Configuring IIS: Mapping .* to the aspnet_isapi.dll
    递归遍历XML生成树
    数据库应用:无法更新到数据库
    C#中HashTable的用法
    如何使用Eclipse编译C,C++,JAVA程序
  • 原文地址:https://www.cnblogs.com/fisherss/p/12104680.html
Copyright © 2011-2022 走看看