zoukankan      html  css  js  c++  java
  • 洛谷 P5357 【模板】AC自动机(二次加强版)

    传送门
    想用后缀数组和后缀自动机来搞这道题,都不成功,不是卡内存就是卡时间,后缀数组有一招二分后缀,但是各种条件不好写,所以还是憋着复习了一下ac自动机。
    学了后缀自动机之后对ac自动机的fail树也更加理解了,一个点的匹配次数其实是fail树上它的子树的匹配次数之和,这和后缀自动机的endpos的原理一模一样。
    这道题直接建树,然后跑主串,匹配的时候不用沿着fail回跳,只需在当前节点+1,然后最后按节点深度排序,就是拓扑序列,统计子树和就可以了,对于每个询问输出对应节点的值。

    #include <bits/stdc++.h>
    using namespace std;
    const int N=2e5+10;
    int n,pos[N];
    char s[N*10],t[N];
    
    struct ACAutomaton{
    	int tot,tr[N][26],fa[N],dep[N],val[N],a[N],c[N];
    	int newnode(){val[++tot]=0;memset(tr[tot],0,sizeof(tr[tot]));return tot;}
    	int insert(){
    		int n=strlen(t+1),p=0;
    		for(int i=1;i<=n;i++){
    			if(!tr[p][t[i]-'a']) tr[p][t[i]-'a']=newnode();
    			dep[tr[p][t[i]-'a']]=dep[p]+1;
    			p=tr[p][t[i]-'a'];
    		}
    		return p;
    	}
    	void getfail(){
    		queue<int> que;
    		for(int i=0;i<26;i++) if(tr[0][i]) que.push(tr[0][i]),fa[tr[0][i]]=0;
    		while(!que.empty()){
    			int u=que.front();que.pop();
    			for(int i=0;i<26;i++)
    				if(tr[u][i]) fa[tr[u][i]]=tr[fa[u]][i],que.push(tr[u][i]);
    				else tr[u][i]=tr[fa[u]][i]; 
    		}
    	}
    	void solve(){
    		int n=strlen(s+1);
    		for(int i=1,p=0;i<=n;i++){
    			int c=s[i]-'a';
    			while(p&&!tr[p][c]) p=fa[p];
    			p=tr[p][c];
    			if(p) val[p]++;
    		}
    		for(int i=1;i<N;i++) c[i]=0;
    		for(int i=1;i<=tot;i++) c[dep[i]]++;
    		for(int i=1;i<N;i++) c[i]+=c[i-1];
    		for(int i=tot;i>=1;i--) a[c[dep[i]]--]=i;
    		for(int i=tot;i>=1;i--) val[fa[a[i]]]+=val[a[i]];
    	}
    }ac;
    
    int main(){
    	ac.tot=0;memset(ac.tr[0],0,sizeof(ac.tr[0]));
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++){
    		scanf("%s",t+1);
    		pos[i]=ac.insert();
    	}
    	ac.getfail();
    	scanf("%s",s+1);
    	ac.solve();
    	for(int i=1;i<=n;i++) printf("%d
    ",ac.val[pos[i]]);
    	return 0;
    }
    
  • 相关阅读:
    Tor网络突破IP封锁,爬虫好搭档【入门手册】
    ubuntu python3相关
    toutiao url
    处理跨域请求
    Python使用虚拟环境
    Python删除文件,空文件夹,非空文件夹
    如何在jupyter中使用Python2和Python3
    推荐使用国内的豆瓣源安装Python插件
    Python数据库查询之组合条件查询-F&Q查询
    获取Django项目的全部url
  • 原文地址:https://www.cnblogs.com/BakaCirno/p/12711938.html
Copyright © 2011-2022 走看看