• BZOJ 4448: [Scoi2015]情报传递 DFS序+主席树


    对与每一个时刻用主席树维护一下 DFS 序即可.          

    LCA 的话树剖求解比较快. 

    code:  

    #include <cstdio>   
    #include <string> 
    #include <cstring>
    #include <algorithm>  
    
    #define N 200006 
    
    using namespace std; 
    
    namespace IO { 
    
        void setIO(string s) 
        {
            string in=s+".in"; 
            string out=s+".out"; 
            freopen(in.c_str(),"r",stdin); 
            freopen(out.c_str(),"w",stdout); 
        }
    
    }; 
    
    namespace se {   
    
        #define lson t[x].ls 
        #define rson t[x].rs 
    
        struct node { 
            int ls,rs,sum;      
        }t[N*50]; 
        int tot; 
    
        int newnode() { return ++tot; }   
    
        void build(int &x,int l,int r) 
        {
            x=newnode(); 
            if(l==r) return; 
            int mid=(l+r)>>1;  
            build(lson,l,mid),build(rson,mid+1,r);         
        }
    
        int update(int pre,int l,int r,int p,int v) 
        {        
            int x=newnode();     
            t[x]=t[pre];   
            t[x].sum=t[pre].sum+v;    
            if(l==r) return x;   
            int mid=(l+r)>>1;   
            if(p<=mid)  lson=update(t[pre].ls,l,mid,p,v); 
            else rson=update(t[pre].rs,mid+1,r,p,v);    
            return x; 
        }    
    
        int query(int x,int l,int r,int L,int R) 
        {
            if(!x) return 0; 
            if(l>=L&&r<=R)  return t[x].sum; 
            int re=0,mid=(l+r)>>1;  
            if(L<=mid)  re+=query(lson,l,mid,L,R); 
            if(R>mid)   re+=query(rson,mid+1,r,L,R);   
            return re;  
        }
    
        #undef lson 
        #undef rson 
    
    }; 
    
    int n,edges,dfn; 
    int hd[N],to[N],nex[N],st[N],ed[N],dep[N],size[N],son[N],top[N],fa[N],Rt[N];    
    
    void add(int u,int v) 
    {  
        nex[++edges]=hd[u],hd[u]=edges,to[edges]=v; 
    }   
    
    void dfs1(int u) 
    {
        st[u]=++dfn; 
        size[u]=1; 
        for(int i=hd[u];i;i=nex[i]) 
        {
            dep[to[i]]=dep[u]+1;   
            dfs1(to[i]); 
            size[u]+=size[to[i]]; 
            if(size[to[i]]>size[son[u]])  son[u]=to[i];    
        } 
        ed[u]=dfn; 
    }
    
    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]) 
        {
            int v=to[i]; 
            if(v==son[u])  continue;   
            dfs2(v,v);   
        }
    }
    
    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 main() 
    { 
        // IO::setIO("input");  
        int i,j,q,rt=0,tim=0; 
        scanf("%d",&n); 
        for(i=1;i<=n;++i) 
        {
            int ff; 
            scanf("%d",&ff); 
            fa[i]=ff;     
            if(!ff)  rt=i;   
            else add(ff,i);  
        }   
        dfs1(rt);   
        dfs2(rt,rt);            
        se::build(Rt[0],1,n);   
        scanf("%d",&q);      
        for(i=1;i<=q;++i) 
        {   
            int op; 
            tim=i;  
            Rt[tim]=Rt[tim-1];   
            scanf("%d",&op);   
            if(op==1) 
            {     
                int x,y,c; 
                scanf("%d%d%d",&x,&y,&c);    
                printf("%d ",dep[x]+dep[y]-2*dep[LCA(x,y)]+1);  
                if(c>=tim)   printf("0
    "); 
                else 
                {                 
                    int x1=0,x2=0,x3=0,x4=0,lca=LCA(x,y);
                    x1=se::query(Rt[tim-c-1],1,n,1,st[x]);   
                    x2=se::query(Rt[tim-c-1],1,n,1,st[y]);      
                    x3=se::query(Rt[tim-c-1],1,n,1,st[lca]);    
                    x4=se::query(Rt[tim-c-1],1,n,1,st[fa[lca]]);   
                    printf("%d
    ",x1+x2-x3-x4);   
                }
            } 
            else 
            {
                int t; 
                scanf("%d",&t);               
                Rt[tim]=se::update(Rt[tim],1,n,st[t],1);                
                if(ed[t]<n) Rt[tim]=se::update(Rt[tim],1,n,ed[t]+1,-1);   
            }
        }       
        return 0; 
    }
    

      

  • 相关阅读:
    Linux下查看某个命令的参数
    Vue
    SpringBoot vue
    Axios 中文说明
    一个很有趣的示例Spring Boot项目,使用Giraphe CMS和Spring Boot
    微信公众号 文章的爬虫系统
    为RecyclerView添加item的点击事件
    Android NineGridLayout — 仿微信朋友圈和QQ空间的九宫格图片展示自定义控件
    今日头条 --新闻阅读器
    int android.support.v7.widget.RecyclerView$ViewHolder.mItemViewType' on a null.....
  • 原文地址:https://www.cnblogs.com/guangheli/p/12100367.html
Copyright © 2020-2023  润新知