• BZOJ 4477: [Jsoi2015]字符串树 可持久化trie树


    这个是真——可持久化字典树.....

    code: 

    #include <bits/stdc++.h>   
    #define N 100006   
    #define setIO(s) freopen(s".in","r",stdin) 
    using namespace std;    
    int n,edges,Q,tot;    
    char val[N<<1][12];      
    int hd[N],to[N<<1],nex[N<<1],top[N],size[N],dep[N],fa[N],rt[N],son[N];   
    struct node 
    { 
        int ch[27],cnt; 
    }t[N*27]; 
    void add(int u,int v,char str[]) 
    { 
        nex[++edges]=hd[u],hd[u]=edges,to[edges]=v;   
        for(int i=strlen(str),j=0;j<i;++j)  val[edges][j]=str[j];      
    }        
    void insert(int pre,int u,char str[]) 
    { 
        int last=rt[pre]; 
        int len=strlen(str);  
        int now=rt[u]=++tot;     
        t[now]=t[last];    
        ++t[now].cnt;   
        for(int i=0;i<len;++i) 
        {    
            t[now].ch[str[i]-'a']=++tot;                         
            last=t[last].ch[str[i]-'a'];   
            now=tot;     
            t[now]=t[last];  
            ++t[now].cnt;  
        }
    }
    int query(int x,char str[]) 
    {
        int len=strlen(str); 
        for(int i=0;i<len;++i)   x=t[x].ch[str[i]-'a'];   
        return t[x].cnt;   
    }
    void dfs1(int u,int ff) 
    { 
        fa[u]=ff,dep[u]=dep[ff]+1,size[u]=1; 
        for(int i=hd[u];i;i=nex[i]) 
        {
            int v=to[i];   
            if(v==ff) continue;       
            insert(u,v,val[i]), dfs1(v,u), size[u]+=size[v];              
            if(size[v]>size[son[u]])   son[u]=v;          
        }
    }
    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]);  
    }
    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() 
    { 
        // setIO("input");   
        int i,j; 
        scanf("%d",&n);   
        for(i=1;i<n;++i) 
        {
            int x,y;  
            char str[12];   
            scanf("%d%d%s",&x,&y,str);   
            add(x,y,str),add(y,x,str);                
        }
        dfs1(1,0); 
        dfs2(1,1);      
        scanf("%d",&Q);   
        while(Q--) 
        {
            int x,y,lca; 
            char str[13]; 
            scanf("%d%d%s",&x,&y,&str);    
            lca=LCA(x,y);      
            printf("%d
    ",query(rt[x],str)+query(rt[y],str)-2*query(rt[lca],str));   
        }
        return 0; 
    }
    

      

  • 相关阅读:
    二十几岁的事情之一,缩小理想!
    mysql数据库建表分类字段--尽量少用字符串--原因探索
    Linux 提升逼格之 命令别名 分享
    git 认证问题之一的解决 : http ssh 互换
    rabbitmqctl 命令整理
    golang 用defer 捕获error 需小心
    Linux 常用命令 随口说
    随便记录几个点
    喜鹊开发者(The Magpie Developer)
    主流开放平台接口说明
  • 原文地址:https://www.cnblogs.com/guangheli/p/11934008.html
Copyright © 2020-2023  润新知