zoukankan      html  css  js  c++  java
  • Jzoj4061 字符串树

    给一个树,每条边上面有一个字符串,每次询问两个节点路径上的字符串中有多少以给定的一个字符串为前缀

    显然是一个十分简单的题目,当时想多了打了树剖+Trie合并

    后来才意识到可以用差分+可持久化trie,过于愚蠢了。。。。。

    其实solution给了另一种解法,将所有字符串排序,哈希求lcp,让后存在一个数组里面,让后就可以用主席树了

    反正这题比较简单

    #pragma GCC opitmize("O3")
    #pragma G++ opitmize("O3")
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #define N 100010
    using namespace std;
    struct edge{ int v,nt; } G[200010]; 
    struct trie{ int c,s[26]; } s[2000010];
    char c[200010][11],o[11];
    int n,m,cnt=0,tot=0,h[N],d[N],f[N],sz[N],son[N],top[N],w[N];
    inline void insert(int r1,int& r2,char* t){
    	if(!r2) r2=++tot; s[r2].c=s[r1].c+1;
    	if(*t){
    		for(int i=0;i<26;++i) if(i+'a'!=*t) s[r2].s[i]=s[r1].s[i];
    		insert(s[r1].s[*t-'a'],s[r2].s[*t-'a'],t+1);
    	}	
    }
    inline int count(int r,char* t){
    	for(;r&&*t;++t) r=s[r].s[*t-'a'];
    	return s[r].c;
    }
    inline void adj(int x,int y,char* t){
    	G[++cnt]=(edge){y,h[x]}; h[x]=cnt; 
    	for(int i=0;*t;++t,++i) c[cnt][i]=*t;
    }
    void dfs(int x,int p){
    	d[x]=d[p]+1; f[x]=p; sz[x]=1;
    	for(int v,i=h[x];i;i=G[i].nt)
    		if((v=G[i].v)!=p){
    			insert(w[x],w[v],c[i]);
    			dfs(v,x); sz[x]+=sz[v];
    			if(sz[v]>sz[son[x]]) son[x]=v;
    		}
    }
    void dgs(int x,int p){
    	top[x]=p;
    	if(son[x]) dgs(son[x],p);
    	for(int v,i=h[x];i;i=G[i].nt)
    		if(!top[v=G[i].v]) dgs(v,v);
    }
    inline int gLca(int x,int y,char* o){
    	int v=count(w[x],o)+count(w[y],o);
    	for(;top[x]!=top[y];y=f[top[y]])
    		if(d[top[x]]>d[top[y]]) swap(x,y);
    	if(d[x]>d[y]) swap(x,y);
    	return v-2*count(w[x],o);
    }
    int main(){
    	freopen("strings.in","r",stdin);
    	freopen("strings.out","w",stdout);
    	scanf("%d",&n);
    	for(int x,y,i=1;i<n;++i){
    		scanf("%d%d%s",&x,&y,o);
    		adj(x,y,o); adj(y,x,o);
    	}
    	dfs(1,0); dgs(1,1); scanf("%d",&m);
    	for(int x,y;m--;){
    		scanf("%d%d%s",&x,&y,&o);
    		printf("%d
    ",gLca(x,y,o));
    	}
    }

  • 相关阅读:
    org.springframework.http.converter.HttpMessageNotWritableException: Could not write JSON
    小程序用户表wx_user设计
    CSDN支持语法高亮的常用语言(Markdown使用之)
    查看CentOS版本信息
    Java操作MongoDB之mongodb-driver
    使用SpringCache进行缓存数据库查询
    MYSQL:WARN: Establishing SSL connection without server's identity verification is not recommended.
    SpringDataRedis常用方法
    SpringBoot整合Redis进行缓存数据库查询
    java连接neo4j
  • 原文地址:https://www.cnblogs.com/Extended-Ash/p/9477174.html
Copyright © 2011-2022 走看看