zoukankan      html  css  js  c++  java
  • 【BZOJ4477】[JSOI2015]字符串树(Trie树)

    【BZOJ4477】[JSOI2015]字符串树(Trie树)

    题面

    BZOJ

    题解

    对于每个点维护其到根节点的所有字符串构成的(Trie),显然可持久化一下就很好写了。
    然后每次询问就是(u+v-2lca),写个树剖维护(LCA)就好了。

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    using namespace std;
    #define MAX 100100
    inline int read()
    {
    	int x=0;bool t=false;char ch=getchar();
    	while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
    	if(ch=='-')t=true,ch=getchar();
    	while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
    	return t?-x:x;
    }
    char ch[MAX][15];
    struct Line{int v,next;char *ch;}e[MAX<<1];
    int h[MAX],cnt=1;
    inline void Add(int u,int v,char *s){e[cnt]=(Line){v,h[u],s};h[u]=cnt++;}
    int n,Q,tot;
    struct Node{int son[26],v;}t[MAX<<4];
    void insert(int &x,char *s,int l,int lim)
    {
    	t[++tot]=t[x];t[x=tot].v+=1;if(l>lim)return;
    	insert(t[x].son[s[l]-'a'],s,l+1,lim);
    }
    int Query(int x,char *s,int l)
    {
    	for(int i=1;i<=l;++i)x=t[x].son[s[i]-'a'];
    	return t[x].v;
    }
    int rt[MAX],fa[MAX];
    int size[MAX],hson[MAX],top[MAX],dep[MAX];
    void dfs1(int u,int ff)
    {
    	fa[u]=ff;size[u]=1;dep[u]=dep[ff]+1;
    	for(int i=h[u];i;i=e[i].next)
    	{
    		int v=e[i].v;if(v==ff)continue;
    		insert(rt[v]=rt[u],e[i].ch,1,strlen(e[i].ch+1));
    		dfs1(v,u);size[u]+=size[v];
    		if(size[v]>size[hson[u]])hson[u]=v;
    	}
    }
    void dfs2(int u,int tp)
    {
    	top[u]=tp;
    	if(hson[u])dfs2(hson[u],tp);
    	for(int i=h[u];i;i=e[i].next)
    		if(e[i].v!=fa[u]&&e[i].v!=hson[u])
    			dfs2(e[i].v,e[i].v);
    }
    int LCA(int u,int v)
    {
    	while(top[u]^top[v])(dep[top[u]]<dep[top[v]])?v=fa[top[v]]:u=fa[top[u]];
    	return dep[u]<dep[v]?u:v;
    }
    int main()
    {
    	n=read();
    	for(int i=1;i<n;++i)
    	{
    		int u=read(),v=read();scanf("%s",ch[i]+1);
    		Add(u,v,ch[i]);Add(v,u,ch[i]);
    	}
    	dfs1(1,0);dfs2(1,1);
    	Q=read();
    	while(Q--)
    	{
    		int u=read(),v=read();scanf("%s",ch[0]+1);
    		int l=strlen(ch[0]+1);
    		int ans=Query(rt[u],ch[0],l)+Query(rt[v],ch[0],l)-2*Query(rt[LCA(u,v)],ch[0],l);
    		printf("%d
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    linux 通配符
    linux 常用快捷键
    datatables-2
    datables
    datatables
    http://blog.csdn.net/heqingsong1/article/details/8540665
    软件提升知识点
    深入浅出单实例Singleton设计模式
    详解js跨域问题
    自定义控件之绘图篇(四):canvas变换与操作
  • 原文地址:https://www.cnblogs.com/cjyyb/p/9718398.html
Copyright © 2011-2022 走看看