zoukankan      html  css  js  c++  java
  • bzoj 3172: [Tjoi2013]单词【AC自动机】

    一眼AC自动机,就是先把串建一个自动机,标记每个串在自动机上的位置,然后加上间隔符连成一个串在自动机上跑,每跑到一个点就说明这个串以及它到root的所有点表示的串都要被更新一次
    先在点上打上标记,最后dfs fail数向上传递
    并不是到结尾点才能更新……脑子抽了

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    using namespace std;
    const int N=1000005;
    int n,ch[N][27],fa[N],id[N],a[N],tot=1,con,h[N],cnt;
    char s[N<<1],c[N];
    struct qwe
    {
    	int ne,to;
    }e[N<<1];
    void add(int u,int v)
    {
    	cnt++;
    	e[cnt].ne=h[u];
    	e[cnt].to=v;
    	h[u]=cnt;
    }
    void dfs(int u)
    {
    	for(int i=h[u];i;i=e[i].ne)
    	{
    		dfs(e[i].to);
    		a[u]+=a[e[i].to];
    	}
    }
    int main()
    {
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++)
    	{
    		scanf("%s",c+1);
    		int nw=1;
    		for(int j=1,len=strlen(c+1);j<=len;j++)
    		{
    			s[++con]=c[j]-'a';
    			if(!ch[nw][c[j]-'a'])
    				ch[nw][c[j]-'a']=++tot;
    			nw=ch[nw][c[j]-'a'];
    		}
    		id[i]=nw;
    		s[++con]=26;
    	}
    	queue<int>q;
    	for(int i=0;i<=26;i++)
    	{
    		if(ch[1][i])
    			q.push(ch[1][i]),fa[ch[1][i]]=1;
    		else
    			ch[1][i]=1;
    	}
    	while(!q.empty())
    	{
    		int u=q.front();
    		q.pop();
    		for(int i=0;i<=26;i++)
    		{
    			if(ch[u][i])
    				fa[ch[u][i]]=ch[fa[u]][i],q.push(ch[u][i]);
    			else
    				ch[u][i]=ch[fa[u]][i];
    		}
    	}
    	for(int i=2;i<=tot;i++)
    		add(fa[i],i);
    	int nw=1;
    	for(int i=1;i<=con;i++)
    	{
    		nw=ch[nw][s[i]];
    		a[nw]++;
    	}
    	dfs(1);
    	for(int i=1;i<=n;i++)
    		printf("%d
    ",a[id[i]]);
    	return 0;
    }
    
  • 相关阅读:
    SQL SERVER XML 学习总结
    Azkaban2官方配置文档
    I.MX6 Android CAN 命令行测试
    nginx 静态网站配置
    nginx php 配置
    uwsgi 配置 初试
    django 初试
    Ubuntu Nginx uwsgi django 初试
    I.MX6 天嵌 E9 U-boot menu hacking
    Ubuntu 搭建 LAMP 服务器
  • 原文地址:https://www.cnblogs.com/lokiii/p/10434174.html
Copyright © 2011-2022 走看看