• Luogu4081 USACO17DEC Standing Out from the Herd(广义后缀自动机)


      建出广义SAM,通过parent树对每个节点求出其是否仅被一个子串包含及被哪个包含。

      写了无数个sam板子题一点意思都没啊

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define inf 1000000010
    #define N 200010
    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,son[N][26],fail[N],len[N],f[N],q[N],tmp[N],cnt=1,last;
    ll ans[N];
    char s[N];
    int ins(int c,int p,int i)
    {
    	int u;
        if (son[p][c])
        {
            int q=son[p][c];
            if (len[p]+1==len[q]) u=q;
            else
            {
                int y=++cnt;
                len[y]=len[p]+1;
                memcpy(son[y],son[q],sizeof(son[q]));
                fail[y]=fail[q],fail[q]=y;
                while (son[p][c]==q) son[p][c]=y,p=fail[p];
                u=y;
            }
        }
        else
        {
            int x=++cnt;len[x]=len[p]+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];
                }
            }
            u=x;
        }
        if (f[u]==-1) f[u]=i;else if (f[u]!=i) f[u]=0;
        return u;
    }
    signed main()
    {
    #ifndef ONLINE_JUDGE
    	freopen("a.in","r",stdin);
    	freopen("a.out","w",stdout);
    #endif
    	n=read();memset(f,255,sizeof(f));
    	for (int i=1;i<=n;i++)
    	{
    		scanf("%s",s+1);
    		m=strlen(s+1);last=1;
    		for (int j=1;j<=m;j++) last=ins(s[j]-'a',last,i);
    	}
    	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>=1;i--)
    	{
    		int x=q[i];
    		if (f[x]>0) ans[f[x]]+=len[x]-len[fail[x]];
    		if (f[fail[x]]==-1) f[fail[x]]=f[x];
    		else if (f[fail[x]]!=f[x]) f[fail[x]]=0;
    	}
    	for (int i=1;i<=n;i++) printf("%lld
    ",ans[i]);
    	return 0;
    	//NOTICE LONG LONG!!!!!
    }
    

      

  • 相关阅读:
    ASPxGridView之ASPxGridViewExporter
    Asp.net中,从弹出窗体取选择值
    ASPxGridView中常用操作
    asp.net Webconfig
    白皮书 CPU卡基本知识
    Linux 中的计时 转自IBM china
    网络无缝融合技术(转)
    UMA相关的网站
    几本不错的书
    手机基带芯片供应商严阵以待,备战3G市场
  • 原文地址:https://www.cnblogs.com/Gloid/p/10832153.html
Copyright © 2020-2023  润新知