空罐Cans (ac自动机 dp)

来源:互联网 发布:himall 2.4 sqlserver 编辑:程序博客网 时间:2024/06/11 18:58

忘记了 这一句  val[u] |= val[f[u]];///!!!

参考:http://blog.csdn.net/no__stop/article/details/8943271

另有:

hdu 3341 Lost's revenge关于压缩的技巧

lightoj 1427 Substring Frequency (II) (ac自动机)在fail树上的拓扑

。。。

#pragma comment(linker, "/STACK:1024000000,1024000000")#include <cstdio>#include <ctime>#include <cstdlib>#include <cstring>#include <queue>#include <string>#include <set>#include <stack>#include <map>#include <cmath>#include <vector>#include <iostream>#include <algorithm>using namespace std;#define FE(i, a, b) for(int i = (a); i <= (b); ++i)#define FD(i, b, a) for(int i = (b); i >= (a); --i)#define REP(i, N) for(int i = 0; i < (N); ++i)#define CLR(a, v) memset(a, v, sizeof(a))#define PB push_back#define MP make_pairtypedef long long LL;const int INF = 0x3f3f3f3f;const int MOD = 10007;const int maxn = 1555;const int SIG = 4;int dp[2][111][maxn];int ans1, ans2;int n, p;struct AC{    int ch[maxn][SIG];    int f[maxn];    int dep[maxn];    int val[maxn];    int sz;    int newnode(int deep)///!!!    {        CLR(ch[sz], 0);        dep[sz] = deep;        val[sz] = 0;        return sz++;    }    void init()    {        sz = 0;        newnode(0);    }    int idx(char c) { return c-'a'; }    void insert(char *s)    {        int u=0,n=strlen(s);        int d = 0;        for(int i=0;i<n;i++)        {            d++;            int c=idx(s[i]);            if(!ch[u][c]) ch[u][c] = newnode(d);            u = ch[u][c];        }        val[u] = 1;    }    void getFail()    {        queue<int> q;        f[0] = 0;        for(int c = 0; c < SIG; c++)        {            int u = ch[0][c];            if(u) { f[u] = 0; q.push(u); }        }        while(!q.empty())        {            int r = q.front(); q.pop();            for(int c = 0; c < SIG; c++)            {                int  u = ch[r][c];                if(!u) { ch[r][c] = ch[f[r]][c]; continue; }                q.push(u);                int v = f[r];                while(v && !ch[v][c]) v = f[v];                f[u] = ch[v][c];                val[u] |= val[f[u]];///!!!            }        }    }    void solve(char *s)    {        int len = strlen(s);        CLR(dp, 0);        int fla = 0;        int uu = 0;        for (int i = 0; i < len; i++)        {            int c = idx(s[i]);            uu = ch[uu][c];            if (val[uu]) fla = 1;        }        if (fla) { ans1 = 0; ans2 = 1; return; }        dp[0][len][uu] = 1;        int now, next;        now = 0;        for (int i = 0; i <= p; i++)        {            next = now ^ 1;            for (int r = 0; r < sz; r++)            {                ans1 += dp[now][0][r];                ans1 %= MOD;///!!!                for (int j = 1; j <= 100; j++)                {                    int tmp = dp[now][j][r];                    if (!tmp) continue;                    if (val[r]) { ans2 += tmp; ans2 %= MOD; continue; }///!!!                    for (int g = 0; g < 4; g++)                    {                        int u = ch[r][g];                        dp[next][j + 1][u] += tmp;                        dp[next][j + 1][u] %= MOD;                    }                    if (dep[r] <= j - 1) dp[next][j - 1][r] += tmp, dp[next][j - 1][r] %= MOD;                    else dp[next][j - 1][f[r]] += tmp, dp[next][j - 1][f[r]] %= MOD;                }            }            CLR(dp[now], 0);            now ^= 1;        }    }}ac;char s[maxn];char ca[maxn];int main(){    while (~scanf("%s", s))   {        scanf("%d%d", &p, &n);        ac.init();        for (int i = 1; i <= n; i++)        {            scanf("%s", ca);            ac.insert(ca);        }        ac.getFail();        ans1 = ans2 = 0;        ac.solve(s);        printf("%d %d\n", ans1, ans2);   }    return 0;}


原创粉丝点击