zoukankan      html  css  js  c++  java
  • 【xsy1214】 异或路径(xorpath) 点分治+可持久化trie

    题目大意:给你一棵$n$个点的树,每个点有一个点权$x$,问你所有路径中点权异或和最大的路径的异或和

    数据范围:$n≤30000$,$x≤2^{31}-1$。

    如果是边上有点权的话非常简单,直接一个$trie$就可以水过去了。

    然而这题是点权,非常烦人。我们考虑用点分治去解决。

    假设当前需要遍历的树的重心是$x$,我们开一个可持久化$trie$,我们用$son[x][i]$表示$x$的第$i$个儿子(我们假设总共有$p_x$个),将从$son[x][i]$出发的路径异或和加入第$[i,p_x]$个$trie$树中,当我们遍历出一条从$x$出发,经过$son[x][i]$的路径时,我们把这个路径的异或和放入第$i-1$个$trie$树中进行搜索。

    我们已知点分治的时间复杂度是$O(n log n)$,由于这里面套了一个可持久化$trie$,那么时间复杂度就是$O(n log n log_2^{max{x}}$。

    然后我的$trie$树出了锅,路径长度的最后一个二进制位没有被塞进$trie$中,然后成功$GG$

      1 #include<bits/stdc++.h>
      2 #define M 100005
      3 #define INF 19260817
      4 using namespace std;
      5 
      6 struct edge{int u,next;}e[M*2]={0}; int head[M]={0},Use=0;
      7 void add(int x,int y){Use++;e[Use].u=y;e[Use].next=head[x];head[x]=Use;}
      8 
      9 int num[M]={0},vis[M]={0};
     10 
     11 int siz[M]={0};
     12 
     13 void dfssiz(int x,int fa){
     14     siz[x]=1;
     15     for(int i=head[x];i;i=e[i].next)
     16     if(e[i].u!=fa&&vis[e[i].u]==0){
     17         dfssiz(e[i].u,x);
     18         siz[x]+=siz[e[i].u];
     19     }
     20 }
     21 int minn,minid;
     22 void dfsmax(int x,int fa,int fasiz){
     23     int maxn=fasiz-siz[x];
     24     for(int i=head[x];i;i=e[i].next)
     25     if(e[i].u!=fa&&vis[e[i].u]==0){
     26         dfsmax(e[i].u,x,fasiz);
     27         maxn=max(maxn,siz[e[i].u]);
     28     }
     29     if(maxn<minn) minn=maxn,minid=x;
     30 }
     31 
     32 int makeroot(int x){
     33     dfssiz(x,0);
     34     minn=INF; minid=0;
     35     dfsmax(x,0,siz[x]);
     36     return minid;
     37 }
     38 
     39 struct trie{
     40     int a[2];
     41 }a[M*20]={0};int root[M]={0},use=0;
     42 
     43 void add(int &x,int zhi,int wei){
     44     a[++use]=a[x]; x=use; int hh=0;
     45     if(wei<0) return;
     46     if((1<<wei)&zhi) hh=1;
     47     add(a[x].a[hh],zhi,wei-1);
     48 }
     49 int query(int x,int zhi,int wei){
     50     if(wei<0||x==0) return 0; 
     51     int hh=1,ans=0;
     52     if((1<<wei)&zhi) hh=0;
     53     if(!a[x].a[hh]) return query(a[x].a[hh^1],zhi,wei-1);
     54     else return (1<<wei)+query(a[x].a[hh],zhi,wei-1);
     55 }
     56 
     57 void dfsdis(int x,int fa,int hh,int cnt){
     58     hh^=num[x];
     59     add(root[cnt],hh,30);
     60     for(int i=head[x];i;i=e[i].next)
     61     if(e[i].u!=fa&&vis[e[i].u]==0){
     62         dfsdis(e[i].u,x,hh,cnt);
     63     }
     64 }
     65 
     66 int ans=0;
     67 
     68 void query(int x,int fa,int hh,int cnt){
     69     hh^=num[x];
     70     int now=query(root[cnt-1],hh,30);
     71     ans=max(ans,now);
     72     ans=max(ans,hh);
     73     for(int i=head[x];i;i=e[i].next)
     74     if(e[i].u!=fa&&vis[e[i].u]==0){
     75         query(e[i].u,x,hh,cnt);
     76     }
     77 }
     78 
     79 void calc(int x){
     80     int cnt=0;
     81     for(int i=head[x];i;i=e[i].next)
     82     if(vis[e[i].u]==0){
     83         cnt++; root[cnt]=root[cnt-1];
     84         dfsdis(e[i].u,x,0,cnt);
     85     }
     86     cnt=0;
     87     for(int i=head[x];i;i=e[i].next)
     88     if(vis[e[i].u]==0){
     89         cnt++;
     90         ans=max(ans,num[x]);
     91         query(e[i].u,x,num[x],cnt);
     92     }
     93     use=0; memset(root,0,(cnt+1)<<2);
     94 }
     95 
     96 void dfs(int x){
     97     x=makeroot(x); vis[x]=1; 
     98     calc(x);
     99     for(int i=head[x];i;i=e[i].next)
    100     if(vis[e[i].u]==0) dfs(e[i].u);
    101 }
    102 
    103 int main(){
    104 //    freopen("in.txt","r",stdin);
    105 //    freopen("out.txt","w",stdout);
    106     int n; scanf("%d",&n);
    107     for(int i=1;i<=n;i++) scanf("%d",num+i);
    108     for(int i=1;i<n;i++){
    109         int x,y; scanf("%d%d",&x,&y);
    110         add(x,y); add(y,x);
    111     }
    112     dfs(1);
    113     cout<<ans<<endl;
    114 }
  • 相关阅读:
    Head first javascript(七)
    Python Fundamental for Django
    Head first javascript(六)
    Head first javascript(五)
    Head first javascript(四)
    Head first javascript(三)
    Head first javascript(二)
    Head first javascript(一)
    Sicily 1090. Highways 解题报告
    Python GUI programming(tkinter)
  • 原文地址:https://www.cnblogs.com/xiefengze1/p/9384740.html
Copyright © 2011-2022 走看看