zoukankan      html  css  js  c++  java
  • LOJ6583 ICPC World Finals 2019何以伊名始(广义后缀自动机)

      对trie建SAM,询问串倒过来跑到的节点的|right|即为答案。

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define inf 1000000010
    #define N 2000010
    char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
    int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
    int read()
    {
    	int x=0,f=1;char c=getchar();
    	while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
    	while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return x*f;
    }
    int n,m,trie[N][26],son[N][26],fail[N],len[N],size[N],tmp[N],id[N],q[N],cnt=1;
    char s[N];
    int ins(int c,int p)
    {
        int x=++cnt;len[x]=len[p]+1;size[x]=1;
        while (!son[p][c]&&p) son[p][c]=x,p=fail[p];
        if (!p) fail[x]=1;
        else
        {
            int q=son[p][c];
            if (len[p]+1==len[q]) fail[x]=q;
            else
            {
                int y=++cnt;
                len[y]=len[p]+1;
                memcpy(son[y],son[q],sizeof(son[q]));
                fail[y]=fail[q],fail[x]=fail[q]=y;
                while (son[p][c]==q) son[p][c]=y,p=fail[p];
            }
        }
        return x;
    }
    int run(char *s)
    {
    	int n=strlen(s+1);
    	int k=1;for (int i=n;i>=1;i--) k=son[k][s[i]-'A'];
    	return k;
    }
    signed main()
    {
    #ifndef ONLINE_JUDGE
    	freopen("a.in","r",stdin);
    	freopen("a.out","w",stdout);
    #endif
    	n=read(),m=read();
    	for (int i=1;i<=n;i++)
    	{
    		char c=getc();int x=read();
    		trie[x][c-'A']=i;
    	}
    	int head=0,tail=1;q[1]=0;id[0]=1;
    	do
    	{
    		int x=q[++head];
    		for (int i=0;i<26;i++)
    		if (trie[x][i])
    		{
    			q[++tail]=trie[x][i];
    			id[q[tail]]=ins(i,id[x]);
    		}
    	}while (head<tail);
    	for (int i=1;i<=cnt;i++) tmp[len[i]]++;
    	for (int i=1;i<=cnt;i++) tmp[i]+=tmp[i-1];
    	for (int i=1;i<=cnt;i++) q[tmp[len[i]]--]=i;
    	for (int i=cnt;i>=2;i--) size[fail[q[i]]]+=size[q[i]];
    	while (m--)
    	{
    		scanf("%s",s+1);
    		printf("%d
    ",size[run(s)]);
    	}
    	return 0;
    	//NOTICE LONG LONG!!!!!
    }
    

      

  • 相关阅读:
    MyEclipse 中文注释乱码
    MyEclipse 代码提示设置
    Java 不使用科学计数法表示数据设置
    Java 环境变量配置
    DateTime & UTC 相互转化
    Redis--Latest Windows Version
    Oracle 锁模式
    <a>链接添加样式问题
    PowerDesigner导出表到word
    HelloWord
  • 原文地址:https://www.cnblogs.com/Gloid/p/10831991.html
Copyright © 2011-2022 走看看