Loli_con

AC自动机及trie图 pascal
const maxn=300005;
type data=record
        sum,failed:longint;
        son:array ['a'..'z'] of longint;
     end;

var tree:array [0..maxn] of data;
    que:array[0..maxn] of longint;
    boo:array[0..maxn] of boolean;
    s:array[0..1000101] of char;
    test,n,len,tot,ans:longint;

procedure PK(x:longint);
begin
    fillchar(tree[x].son,sizeof(tree[x].son),0);
    tree[x].sum:=0;
    tree[x].failed:=-1;
end;

procedure init;

procedure insert;
var p,i:longint;
begin
    p:=0;
    for i:=1 to len do
    begin
        if tree[p].son[s[i]]=0 then
        begin
            inc(tot);
            PK(tot);
            tree[p].son[s[i]]:=tot;
            p:=tot;
        end else p:=tree[p].son[s[i]];
    end;
    inc(tree[p].sum);
end;

var i:longint;
begin
    fillchar(boo,sizeof(boo),false);
    tot:=0;
    PK(0);
    readln(n);
    for i:=1 to n do
    begin
        len:=0;
        while not eoln do
        begin
            inc(len);
            read(s[len]);
            if not(s[len] in ['a'..'z']) then begin dec(len); break; end;
        end;
        readln;
        insert;
    end;
end;

procedure main;

procedure bfs;
var h,t,now,p,f:longint;
    ch:char;
begin
    h:=1;t:=1;
    que[1]:=0;
    while h<=t do
    begin
        now:=que[h];
        for ch:='a' to 'z' do
        begin
            p:=tree[now].son[ch];
            if p<>0 then
            begin
                f:=tree[now].failed;
                while (f<>-1) and (tree[f].son[ch]=0) do f:=tree[f].failed;
                if f=-1 then tree[p].failed:=0
                else tree[p].failed:=tree[f].son[ch];
                inc(t);
                que[t]:=p;
            end;
        end;
        inc(h);
    end;
end;

procedure AC_Automaton;
var i,now,p,f:longint;
begin
    i:=1;
    now:=0;
    while i<=len do
    begin
        p:=tree[now].son[s[i]];
        if p<>0 then
        begin
            f:=p;
            while (not boo[f]) and (f<>0) do
            begin
                boo[f]:=true;
                inc(ans,tree[f].sum);
                f:=tree[f].failed;
            end;
            now:=p;
            inc(i);
        end else
        begin
            f:=now;
            while (f<>-1) and (tree[f].son[s[i]]=0) do f:=tree[f].failed;
            now:=f;
            if now=-1 then
            begin
                now:=0;
                inc(i);
            end;
        end;
    end;
end;

begin
    bfs;
    len:=0;
    while not eoln do
    begin
        inc(len);
        read(s[len]);
        if not(s[len] in ['a'..'z']) then begin dec(len); break; end;
    end;
    readln;
    ans:=0;
    AC_Automaton;
    writeln(ans);
end;

begin
    readln(test);
    while test>0 do
    begin
        init();
        main();
        dec(test);
    end;
end.

 

posted on 2013-11-14 09:57  Loli_con  阅读(490)  评论(0)    收藏  举报