zoukankan      html  css  js  c++  java
  • P2292 [HNOI2004]L语言

    题目

    P2292 [HNOI2004]L语言

    化简题目:多个匹配串,多个文本串,求文本串恰好被匹配串拼接的最长前缀

    做法

    显然我们对文本串建AC自动机,然后标记末节点

    (tire)图,需要注意的是:末节点标记不能下传,原因在于对文本串跑差分的操作,自己想想吧

    多于每个文本串跑(trie)图,对每个字符到达一个点后沿着(fail)往上跑,如果是末节点,说明我们匹配到一个串了,然后做差分就好了

    My complete code

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<string>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    using namespace std;
    typedef int LL;
    const LL maxn=1e6;
    LL nod=1;
    LL son[maxn][26],fail[maxn],dep[maxn];
    bool falg[maxn];
    inline void Insert(char *s){
    	LL Len=strlen(s+1),now=0;
    	for(LL i=1;i<=Len;++i){
    		LL c=s[i]-'a';
    		if(son[now][c]==0){
    		    son[now][c]=++nod;
    		    //dep[nod]=dep[now]+1;
    		}
    		now=son[now][c];
    		dep[now]=i;
    	}falg[now]=true;
    }
    LL n,T;
    LL cf[maxn];
    bool visit[maxn];
    char s[maxn];
    inline void F_fail(){
    	queue<LL>que;
    	for(LL i=0;i<26;++i)
    	    if(son[0][i])
    	        que.push(son[0][i]);
    	while(que.size()){
    		LL u(que.front()); que.pop();
    		for(LL i=0;i<26;++i){
    			LL v(son[u][i]);
    			if(v){
    				fail[v]=son[fail[u]][i],
    				que.push(v);
    			}else
    			    son[u][i]=son[fail[u]][i];
    		}
    	}
    }
    int main(){
    	scanf("%d%d",&n,&T);
    	for(LL i=1;i<=n;++i){
    		scanf(" %s",s+1);
    		Insert(s);
    	}
    	F_fail();
    	while(T--){
    		scanf(" %s",s+1);
    		LL now(0),Len=strlen(s+1);
    		memset(visit,false,sizeof(visit));memset(cf,0,sizeof(cf));
    		visit[0]=true;
    		for(LL i=1;i<=Len;++i){
    			LL c=s[i]-'a';
    			now=son[now][c];
    			for(LL u=now;u;u=fail[u])
    			    if(falg[u]&&visit[i-dep[u]]){
    				    visit[i]=true,
    				    ++cf[i-dep[u]+1],
    				    --cf[i+1];
    			    }
    		}now=0; LL ans(0);
    		for(LL i=1;i<=Len;++i){
    			now+=cf[i];
    			if(now==0)
    			    break;
    			else
    			    ++ans;
    		}
    		printf("%d
    ",ans);
    	}
    }/*
    */
    
  • 相关阅读:
    make clean,make distclean与make depend的区别
    HSTS 与 307 状态码
    阿里云CentOS中vsftp安装、配置、卸载
    vsftp管理脚本(CentOS6用)
    通过修改源码,免插件实现wordpress去除链接中的category
    (转载)Peter Norvig:十年学会编程
    BT觀念分享和常見問題彙整
    Mysql 字符编码
    Mysql 整数类型的字段的属性设置及常用的函数
    MySql快速入门
  • 原文地址:https://www.cnblogs.com/y2823774827y/p/10297335.html
Copyright © 2011-2022 走看看