BZOJ 2780接尾辞オートマトン


英語の問題ですから、簡単に説明してください.
n個のサブストリングとm個のクエリが与えられ始め、各クエリに対して1つのサブストリングが読み込まれ、n個のサブストリングのうち、クエリされたサブストリングが含まれるサブストリングがどれだけあるかを尋ねる.
本当に読めないのはサンプルから気に入ってもらえます.
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
const int maxn =505000;
int n,m,cnt,tot,len,ans[maxn];
char s[maxn];
vector<int> f[maxn];
set<int> T[maxn];
set<int> :: iterator it;
struct sam
{
    int last,dfn;
    int seq[maxn],a[maxn][27],mx[maxn],fa[maxn],sum[maxn];
    sam(){
        last=cnt++;
    }
    void insert(int c,int id)
    {
        int p=last,np=last=++cnt;mx[np]=mx[p]+1;T[np].insert(id); 
        while(!a[p][c]&&p) a[p][c]=np,p=fa[p];
        if(!p) fa[np]=1;
        else
        {
            int q=a[p][c];
            if(mx[p]+1==mx[q]) fa[np]=q;
            else
            {
                int nq=++cnt;mx[nq]=mx[p]+1;
                memcpy(a[nq],a[q],sizeof(a[q]));
                fa[nq]=fa[q];
                fa[np]=fa[q]=nq;
                while(a[p][c]==q) a[p][c]=nq,p=fa[p];
            }
        } 
    }
    void dfs(int u)
    {
        for(int i=0;iint v=f[u][i];
            dfs(v);
            if(T[u].size()for(it=T[v].begin();it!=T[v].end();it++)
                T[u].insert(*it);
        }
        sum[u]=T[u].size();
    }
    void work()
    {
        for(int i=1;i<=n;i++){
            scanf("%s",s);
            last=1;len=strlen(s);
            for(int j=0;j'a',i);
        }
        for(int i=1;i<=cnt;i++) f[fa[i]].push_back(i);
        dfs(1);
        for(int i=1;i<=m;i++){
            bool flag=true;
            scanf("%s",s);int l=strlen(s),p=1;
            for(int j=0;jint c=s[j]-'a';
                if(!a[p][c]) {flag=false;break;}
                p=a[p][c];
            }
            if(flag) printf("%d
"
,sum[p]);             else puts("0");         }     } }sam; int main() {     scanf("%d%d",&n,&m);     sam.work();     return 0; } /* 3 3   abcabcabc   aaa   aafe   abc   a   ca   */