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\n",query(rt[x],str)+query(rt[y],str)-2*query(rt[lca],str));   
    }
    return 0; 
}

  

posted @ 2019-11-26 10:56  EM-LGH  阅读(127)  评论(0编辑  收藏  举报