zoukankan      html  css  js  c++  java
  • POJ 3764 The xor-longest Path (01字典树)

    <题目链接>

    题目大意:

    给定一颗$n$个节点$(nleq10^5)$,有边权的树,其边权$(0leq w < 2^{31})$。让你求出这棵树上任意两个节点之间的异或最大值。

    解题分析:

    先用DFS预处理出根节点到所有节点的路径异或值,然后任意两点$u,v$之间的路径异或值就能通过 $(u->rt) xor (v->rt)$的异或值得到,因为根节点到u、v的最近公共祖先的路径被异或了两次,所以能够直接得到u,v之间的异或距离。但是因为节点数量有$10^5$个,直接枚举两两节点肯定超时。用01字典树优化一下,快速找到异或的最大值。

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <iostream>
    using namespace std;
    
    typedef long long ll;
    
    template<typename T>
    inline void read(T&x){     
      x=0;int f=1;char ch=getchar();
      while(ch<'0' ||ch>'9'){ if(ch=='-')f=-1; ch=getchar(); }
      while(ch>='0' && ch<='9'){ x=x*10+ch-'0'; ch=getchar(); }
      x*=f;
    }
    
    #define rep(i,s,t) for(int i=s;i<=t;i++)
    #define clr(a,b) memset(a,b,sizeof(a))
    const int N = 1e5+5;
    ll nxt[N*32][2],xoval[N];
    int n,rt;
    
    struct Edge{int to,nxt;ll w; }e[N<<1];
    int head[N],cnt,pos;
    
    inline void init(){
      cnt=0;clr(head,-1);
      pos=1;clr(nxt,0);clr(xoval,0);
    }
    inline void add(int u,int v,int w){
      e[cnt]=(Edge){v,head[u],w};head[u]=cnt++;
    }
    void dfs(int u,int pre,ll nowval){     //得到根到所有点的异或值
      xoval[u]=nowval;
      for(int i=head[u];~i;i=e[i].nxt){
        int v=e[i].to;
        if(v==pre)continue;
        dfs(v,u,nowval^e[i].w);
      }
    }
    inline void Insert(ll x){
      int now=1;
      for(int i=30;i>=0;i--){
        int to=(x>>i)&1;
        if(!nxt[now][to])nxt[now][to]=++pos;
        now=nxt[now][to];
        //num[now]++;
      }
    }
    /*inline void del(ll x){      //将01字典树中删除x
        int now=1;
        for(int i=30;i>=0;i--){
            int to=(x>>i)&1;
            num[now]--;
            now=nxt[now][to];
        }
    }*/
    inline ll query(ll x){
      int now=1;ll ans=0;
      for(int i=30;i>=0;i--){
        int to=(x>>i)&1;
        if(nxt[now][to^1])now=nxt[now][to^1],ans+=(1<<i);
        else now=nxt[now][to];
      }
      return ans;
    }
    int main(){
      while(~scanf("%d",&n)){
        init();
        rep(i,1,n-1){      
            int u,v;ll w;read(u);read(v);read(w);
            add(u,v,w);add(v,u,w);     
        }
        dfs(0,-1,0); 
        ll ans=-1e18;
        rep(i,0,n-1){
            ll res=query(xoval[i]);
            ans=max(ans,res);
            Insert(xoval[i]);
        }
        printf("%lld
    ",ans);
      }
    }
  • 相关阅读:
    ASP.NET MVC and jqGrid 学习笔记 1-基本配置
    您必须先调用“WebSecurity.InitializeDatabaseConnection”方法,然后再调用"WebSecurity"类的任何其他方法。
    Firefox便携版
    SQL Server 2012数据导入SQL Server 2008
    Visual studio 2012 添加 GitHub
    不支持关键字:metadata
    jquery-ui autocomplete 自动完成功能
    由于行255而未能重新格式化文档。已还原为原始格式。
    jquery简介(一)
    什么是JSON
  • 原文地址:https://www.cnblogs.com/00isok/p/10798117.html
Copyright © 2011-2022 走看看