• 【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 }
  • 相关阅读:
    c# 代码控制文件夹权限时,只显示特殊权限的问题
    C#使用SQLite数据库遇到的问题(二)
    GC工作原理
    Thread
    -static
    String 练习题
    更进ATM
    继承 示例
    数组
    求奇偶数
  • 原文地址:https://www.cnblogs.com/xiefengze1/p/9384740.html
Copyright © 2020-2023  润新知