zoukankan      html  css  js  c++  java
  • 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
    ",query1(seq[dfn[x]-1],seq[ed[x]],y));         
            }  
            else
            { 
                scanf("%d%d%d",&x,&y,&z);   
                int t=LCA(x,y); 
                printf("%d
    ",query2(tree[x],tree[y],tree[t],tree[fa[t]],z));   
            }
        }
        return 0;
    }
    

      

  • 相关阅读:
    归并排序
    快速排序
    希尔排序
    插入排序
    选择排序
    冒泡排序
    排序算法
    Win10 家庭版升级到专业版报错
    WPF 原生Style
    在线图片转换
  • 原文地址:https://www.cnblogs.com/guangheli/p/11934829.html
Copyright © 2011-2022 走看看