BZOJ 5338: [TJOI2018]xor 可持久化trie+dfs序

强行把序列问题放树上,好无聊啊~  

code: 

#include <bits/stdc++.h>        
#define N 200005   
#define setIO(s) freopen(s".in","r",stdin) 
using namespace std;     
int tot,edges,tim;   
int cnt[N*33],ch[N*33][2],tree[N],seq[N],val[N],ba[N];         
int fa[N],son[N],size[N],top[N],dep[N],hd[N],to[N<<1],nex[N<<1],dfn[N],ed[N];     
inline void add(int u,int v) 
{
    nex[++edges]=hd[u],hd[u]=edges,to[edges]=v;   
}
void insert(int pre,int &x,int v) 
{  
    int now=x=++tot;                 
    for(int i=30;i>=0;--i)                  
    {
        int o=((v>>i)&1);      
        ch[now][o^1]=ch[pre][o^1];        
        ch[now][o]=++tot;                      
        pre=ch[pre][o];  
        now=tot;          
        cnt[now]=cnt[pre]+1;  
    }    
}   
void dfs1(int u,int ff) 
{
    fa[u]=ff,dep[u]=dep[ff]+1,size[u]=1,dfn[u]=++tim,ba[tim]=u;   
    for(int i=hd[u];i;i=nex[i]) 
    {
        int v=to[i]; 
        if(v==ff)    continue;         
        insert(tree[u],tree[v],val[v]);             
        dfs1(v,u); 
        size[u]+=size[v]; 
        if(size[v]>size[son[u]])       son[u]=v;   
    }
    ed[u]=tim;   
}   
void dfs2(int u,int tp) 
{   
    top[u]=tp;   
    if(son[u])    dfs2(son[u],tp); 
    for(int i=hd[u];i;i=nex[i])     if(to[i]!=fa[u]&&to[i]!=son[u])   dfs2(to[i],to[i]);       
}
inline int LCA(int x,int y) 
{
    while(top[x]!=top[y])    dep[top[x]]>dep[top[y]]?x=fa[top[x]]:y=fa[top[y]];   
    return dep[x]<dep[y]?x:y;   
}
int query1(int x,int y,int z) 
{
    int re=0;  
    for(int i=30;i>=0;--i)                      
    {  
        int o=((z>>i)&1);     
        if(cnt[ch[y][o^1]]>cnt[ch[x][o^1]])   
        {      
            re+=(1<<i);   
            y=ch[y][o^1]; 
            x=ch[x][o^1]; 
        } 
        else 
        {
            y=ch[y][o]; 
            x=ch[x][o];          
        }
    }
    return re;   
}
int query2(int x,int y,int lca,int ff,int z) 
{   
    int re=0;  
    for(int i=30;i>=0;--i) 
    {
        int o=((z>>i)&1);   
        if(cnt[ch[x][o^1]]+cnt[ch[y][o^1]]-cnt[ch[lca][o^1]]-cnt[ch[ff][o^1]]) 
        {
            re+=(1<<i);   
            x=ch[x][o^1]; 
            y=ch[y][o^1]; 
            lca=ch[lca][o^1]; 
            ff=ch[ff][o^1]; 
        } 
        else 
        {
            x=ch[x][o]; 
            y=ch[y][o]; 
            lca=ch[lca][o]; 
            ff=ch[ff][o];   
        }
    } 
    return re;    
}
int main() 
{ 
    // setIO("input");
    int i,j,n,m; 
    scanf("%d%d",&n,&m);      
    for(i=1;i<=n;++i)      scanf("%d",&val[i]);        
    for(i=1;i<n;++i)  
    {
        int x,y; 
        scanf("%d%d",&x,&y),   add(x,y), add(y,x);  
    } 
    insert(tree[0],tree[1],val[1]);        
    dfs1(1,0); 
    dfs2(1,1);         
    for(i=1;i<=tim;++i)      insert(seq[i-1],seq[i],val[ba[i]]);           
    while(m--) 
    {
        int op,x,y,z; 
        scanf("%d",&op);  
        if(op==1) 
        { 
            scanf("%d%d",&x,&y);            
            printf("%d\n",query1(seq[dfn[x]-1],seq[ed[x]],y));         
        }  
        else
        { 
            scanf("%d%d%d",&x,&y,&z);   
            int t=LCA(x,y); 
            printf("%d\n",query2(tree[x],tree[y],tree[t],tree[fa[t]],z));   
        }
    }
    return 0;
}

  

posted @ 2019-11-26 13:23  EM-LGH  阅读(122)  评论(0编辑  收藏  举报