AC自动机

ZOJ 3430 Detect the Virus

挺扯的一个题,解码有点问题+注意用int存,跟HDU2222差不多...

#include <iostream>

#include <cstring>

#include <cstdio>

#include <queue>

#include <algorithm>

#include <cstdlib>

using namespace std;

#define N 60010

int trie[N][260];

int que[100000];

int fail[100000];

int hash[1001];

int o[100001];

int str[100000];

int t,num;

void CL()

{

    memset(trie,-1,sizeof(trie));

    memset(o,0,sizeof(o));

    t = 1;

}

int fun(char x)

{

    if(x >= 'A'&&x <= 'Z')

        return x-'A';

    else if(x >= 'a'&&x <= 'z')

        return x-'a'+26;

    else if(x >= '0'&&x <= '9')

        return x-'0'+52;

    else if(x == '+')

        return 62;

    else

        return 63;

}

void judge(char *s)

{

    int i,j,len,temp,n;

    len = strlen(s);

    n = 0;

    for(i = 0; i < len; i ++)

    {

        if(s[i] == '=')

        {

            n -= 2;//开始这里没理解对。

            continue;

        }

        temp = fun(s[i]);

        for(j = 5; j >= 0; j --)

        {

            if(temp&(1<<j))

                que[n++] = 1;

            else

                que[n++] = 0;

        }

    }

    for(i = 0; i < n;)

    {

        str[i/8] = 0;

        for(j = 7; j >= 0; j --)

        {

            if(que[i])

                str[i/8] += 1<<j;

            i ++;

        }

    }

    num = n/8;

}

void insert(int x)

{

    int i,len,root;

    len = num;

    root = 0;

    for(i = 0; i < len; i ++)

    {

        if(trie[root][str[i]] == -1)

        {

            trie[root][str[i]] = t ++;

        }

        root = trie[root][str[i]];

    }

    o[root] = x;

}

void build_ac()

{

    int head,tail,front,i;

    head = tail = 0;

    for(i = 0; i < 260; i ++)

    {

        if(trie[0][i] != -1)

        {

            fail[trie[0][i]] = 0;

            que[tail++] = trie[0][i];

        }

        else

        {

            trie[0][i] = 0;

        }

    }

    while(head != tail)

    {

        front = que[head++];

        for(i = 0; i < 260; i ++)

        {

            if(trie[front][i] != -1)

            {

                que[tail++] = trie[front][i];

                fail[trie[front][i]] = trie[fail[front]][i];

            }

            else

            {

                trie[front][i] = trie[fail[front]][i];

            }

        }

    }

}

void query()

{

    int len,key,temp,i,root;

    root = 0;

    len = num;

    for(i = 0; i < len; i ++)

    {

        temp = str[i];

        root = trie[root][temp];

        key = root;

        while(key != 0)

        {

            hash[o[key]] = 1;

            key = fail[key];

        }

    }

}

int main()

{

    int n,i,m,j;

    char ch[5000];

    while(scanf("%d",&n)!=EOF)

    {

        CL();

        for(i = 1; i <= n; i ++)

        {

            scanf("%s",ch);

            judge(ch);

            insert(i);

        }

        build_ac();

        scanf("%d",&m);

        for(i = 0; i < m; i ++)

        {

            memset(hash,0,sizeof(hash));

            scanf("%s",ch);

            judge(ch);

            query();

            int ans = 0;

            for(j = 1; j <= n; j ++)

            {

                if(hash[j])

                    ans ++;

            }

            printf("%d\n",ans);

        }

        printf("\n");

    }

    return 0;

}
View Code

 HDU 2996 Ring 

记录路径有点麻烦,注意答案为0的时候输出空。

#include <cstdio>

#include <cstring>

#include <iostream>

using namespace std;

#define N 51000

int trie[N][26];

int fail[N];

int o[N];

int que[N];

int w[101];

int t;

char str[101][101];

int dp[101][1001];

int in[101][1001];

void CL()

{

    memset(trie,-1,sizeof(trie));

    memset(o,0,sizeof(o));

    memset(dp,-1,sizeof(dp));

    memset(in,0,sizeof(in));

    t = 1;

}

void insert(char *s,int num)

{

    int i,len,root;

    root = 0;

    len = strlen(s);

    for(i = 0;i < len;i ++)

    {

        if(trie[root][s[i]-'a'] == -1)

        trie[root][s[i]-'a'] = t ++;

        root = trie[root][s[i]-'a'];

    }

    o[root] = num;

}

void build_ac()

{

    int head,tail,front,i;

    head = tail = 0;

    for(i = 0;i < 26;i ++)

    {

        if(trie[0][i] != -1)

        {

            fail[trie[0][i]] = 0;

            que[tail++] = trie[0][i];

        }

        else

        {

            trie[0][i] = 0;

        }

    }

    while(head != tail)

    {

        front = que[head++];

        o[front] += o[fail[front]];

        for(i = 0;i < 26;i ++)

        {

            if(trie[front][i] != -1)

            {

                que[tail++] = trie[front][i];

                fail[trie[front][i]] = trie[fail[front]][i];

            }

            else

            {

                trie[front][i] = trie[fail[front]][i];

            }

        }

    }

}

int main()

{

    int cas,n,m,i,j,k;

    scanf("%d",&cas);

    while(cas--)

    {

        CL();

        scanf("%d%d",&n,&m);

        for(i = 0;i < m;i ++)

        {

            scanf("%s",str[i]);

        }

        for(i = 0;i < m;i ++)

        {

            scanf("%d",&w[i]);

        }

        for(i = 0;i < m;i ++)

        insert(str[i],w[i]);

        build_ac();

        dp[0][0] = 0;

        for(i = 0;i < n;i ++)

        {

            for(j = 0;j < t;j ++)

            {

                if(dp[i][j] == -1) continue;

                for(k = 0;k < 26;k ++)

                {

                    dp[i+1][trie[j][k]] = max(dp[i][j]+o[trie[j][k]],dp[i+1][trie[j][k]]);

                }

            }

        }

        int ans = 0,root = 0;

        for(i = 1;i <= n;i ++)

        {

            for(j = 0;j < t;j ++)

            ans = max(ans,dp[i][j]);

        }

        if(ans == 0)

        {

            printf("\n");

            continue;

        }

        for(i = 1;i <= n;i ++)

        {

            int s = 0;

            for(j = 0;j < t;j ++)

            {

                if(ans == dp[i][j])

                {

                    in[i][j] = 1;

                    s = 1;

                }

            }

            if(s) break;

        }

        for(i = n-1;i >= 0;i --)

        {

            for(j = 0;j < t;j ++)

            {

                for(k = 0;k < 26;k ++)

                {

                    if(in[i+1][trie[j][k]] == 1&&dp[i][j]+o[trie[j][k]] == dp[i+1][trie[j][k]])

                    in[i][j] = 1;

                }

            }

        }

        root = 0;

        for(i = 1;i <= n;i ++)

        {

            for(j = 0;j < 26;j ++)

            {

                if(in[i][trie[root][j]] && dp[i-1][root] + o[trie[root][j]] == dp[i][trie[root][j]])

                {

                    printf("%c",j+'a');

                    root = trie[root][j];

                    break;

                }

            }

            if(dp[i][trie[root][j]] == ans) break;

        }

        printf("\n");

    }

    return 0;

}
View Code

ZOJ 3228 Searching the String

第一次做,有重复串的。有重复串,直接用指针指向树节点就行了,不能重叠的,标记最后出现的位置就好。

#include <cstdio>

#include <cstring>

#include <iostream>

#include <set>

#include <map>

#include <vector>

#include <cmath>

#include <algorithm>

using namespace std;

#define N 600000

char str[100001];

char ch[100001][6];

int trie[N][26];

int fail[N];

int que[N];

int o[N][2];

int l[N];

int flag[N];

int *ans[100001];

int t;

void CL()

{

    memset(flag,-1,sizeof(flag));

    memset(trie,-1,sizeof(trie));

    memset(o,0,sizeof(o));

    t = 1;

}

void insert(char *s,int num,int type)

{

    int root,len,i;

    root = 0;

    len = strlen(s);

    for(i = 0; i < len; i ++)

    {

        if(trie[root][s[i]-'a'] == -1)

        {

            trie[root][s[i]-'a'] = t ++;

        }

        root = trie[root][s[i]-'a'];

    }

    l[root] = len;

    ans[num] = &o[root][type];

}

void build_ac(char *s)

{

    int head,tail,front,i;

    head = tail = 0;

    for(i = 0; i < 26; i ++)

    {

        if(trie[0][i] != -1)

        {

            fail[trie[0][i]] = 0;

            que[tail++] = trie[0][i];

        }

        else

        {

            trie[0][i] = 0;

        }

    }

    while(head != tail)

    {

        front = que[head++];

        for(i = 0; i < 26; i ++)

        {

            if(trie[front][i] != -1)

            {

                que[tail++] = trie[front][i];

                fail[trie[front][i]] = trie[fail[front]][i];

            }

            else

            {

                trie[front][i] = trie[fail[front]][i];

            }

        }

    }

}

void query(char *s)

{

    int i,len,root,temp,key;

    root = 0;

    len = strlen(s);

    for(i = 0; i < len; i ++)

    {

        temp = s[i] - 'a';

        root = trie[root][temp];

        key = root;

        while(key != 0)

        {

            if(l[key] > 0)

            {

                o[key][0] ++;

                if(i - flag[key] >= l[key])

                {

                    o[key][1] ++;

                    flag[key] = i;

                }

            }

            key = fail[key];

        }

    }

}

int main()

{

    int i,n,cas = 1,temp;

    while(scanf("%s",str)!=EOF)

    {

        CL();

        scanf("%d",&n);

        for(i = 1; i <= n; i ++)

        {

            scanf("%d%s",&temp,ch[i]);

            insert(ch[i],i,temp);

        }

        build_ac(str);

        query(str);

        printf("Case %d\n",cas++);

        for(i = 1; i <= n; i ++)

            printf("%d\n",*ans[i]);

        printf("\n");

    }

    return 0;

}
View Code

HDU 4511 小明系列故事——女友的考验

很非主流的一个题目,我wa了好几页,竟然是没调用build_ac函数,我在宿舍,姿势不大好,一定是这样....这题直接在Trie树上乱搞就好,这个最短路,很特别,两点之间肯定是线段最短,没有必要DP的。

#include <cstdio>

#include <cstring>

#include <iostream>

#include <map>

#include <algorithm>

#include <vector>

#include <cmath>

#include <algorithm>

#include <string>

using namespace std;

double minz;

double x[101],y[101];

int trie[1001][51];

int len[101];

int s[101][101];

int fail[1001];

int que[1001];

int o[1001];

int t,n;

void CL()

{

    memset(trie,-1,sizeof(trie));

    memset(o,0,sizeof(o));

    t = 1;

}

void insert(int x)

{

    int i,root;

    scanf("%d",&len[x]);

    root = 0;

    for(i = 0;i < len[x];i ++)

    {

        scanf("%d",&s[x][i]);

        if(trie[root][s[x][i]] == -1)

        trie[root][s[x][i]] = t ++;

        root = trie[root][s[x][i]];

    }

    o[root] = 1;

}

void build_ac()

{

    int head,tail,i,front;

    head = tail = 0;

    for(i = 1;i <= n;i ++)

    {

        if(trie[0][i] != -1)

        {

            fail[trie[0][i]] = 0;

            que[tail++] =  trie[0][i];

        }

        else

        {

            trie[0][i] = 0;

        }

    }

    while(head != tail)

    {

        front = que[head++];

        if(o[fail[front]]) o[front] = 1;

        for(i = 1;i <= n;i ++)

        {

            if(trie[front][i] != -1)

            {

                que[tail++] = trie[front][i];

                fail[trie[front][i]] = trie[fail[front]][i];

            }

            else

            {

                trie[front][i] = trie[fail[front]][i];

            }

        }

    }

}

double dis(int a,int b)

{

    return sqrt((x[a]-x[b])*1.0*(x[a]-x[b])+(y[a]-y[b])*(y[a]-y[b]));

}

void dfs(int root,double ans,int ve)

{

    int i;

    if(ans >= minz)

    return ;

    if(o[trie[root][n]] == 0)

    {

        minz = min(minz,ans+dis(ve,n));

        return ;

    }

    for(i = ve+1;i <= n;i ++)

    {

        if(o[trie[root][i]]) continue;

        dfs(trie[root][i],ans+dis(ve,i),i);

    }

}

int main()

{

    int m,i;

    while(scanf("%d%d",&n,&m)!=EOF)

    {

        if(n == 0&&m == 0) break;

        CL();

        for(i = 1;i <= n;i ++)

        scanf("%lf%lf",&x[i],&y[i]);

        for(i = 1;i <= m;i ++)

        {

            insert(i);

        }

        build_ac();

        minz = 1000000000.0 * 100000000.0;

        dfs(trie[0][1],0,1);

        if(minz == 1000000000.0 * 100000000.0)

        printf("Can not be reached!\n");

        else

        printf("%.2lf\n",minz);

    }

    return 0;

}
View Code

 HDU 3341 Lost's revenge

我用java过的。。。一个套路的DP+AC自动机,注意有重复串,用java调试的我很纠结。。。eclipse的单步,太难用了。。。单步还是太慢了。。。对java也是各种不熟。

import java.math.BigInteger;

import java.util.Scanner;



public class Main {

    static int t;

    static int trie[][] = new int[1001][4];

    static int o[] = new int[1001];

    static int que[] = new int[1001];

    static int fail[] = new int[1001];



    public static int judge(char s) {

        if (s == 'A')

            return 0;

        else if (s == 'C')

            return 1;

        else if (s == 'G')

            return 2;

        else if (s == 'T')

            return 3;

        return 0;

    }



    public static void CL() {

        int i, j;

        t = 1;

        for (i = 0; i <= 1000; i++) {

            o[i] = 0;

            for (j = 0; j < 4; j++)

                trie[i][j] = -1;

        }

    }



    public static void insert(char s[], int len) {

        // 必须把len传过来

        int root, i;

        root = 0;

        for (i = 0; i < len; i++) {

            if (trie[root][judge(s[i])] == -1)

                trie[root][judge(s[i])] = t++;

            root = trie[root][judge(s[i])];

        }

        o[root] ++;

    }



    public static void build_ac() {

        int i, head, tail, front;

        head = tail = 0;

        for (i = 0; i < 4; i++) {

            if (trie[0][i] != -1) {

                que[tail++] = trie[0][i];

                fail[trie[0][i]] = 0;

            } else {

                trie[0][i] = 0;

            }

        }

        while (head != tail) {

            front = que[head++];

            o[front] += o[fail[front]];

            for (i = 0; i < 4; i++) {

                if (trie[front][i] != -1) {

                    que[tail++] = trie[front][i];

                    fail[trie[front][i]] = trie[fail[front]][i];

                } else {

                    trie[front][i] = trie[fail[front]][i];

                }

            }

        }

    }



    public static void main(String args[]) {

        Scanner cin = new Scanner(System.in);

        int n, i, j, k, u, v, w, x, a, b, c, d, temp, cas = 1;

        String str[] = new String[51];

        char ch[] = new char[101];

        String s;

        while (cin.hasNext()) {

            a = b = c = d = 0;

            n = cin.nextInt();

            if (n == 0)

                break;

            cin.nextLine();

            CL();

            

            for (i = 0; i < n; i++) {

                str[i] = cin.nextLine();

                ch = str[i].toCharArray();

                insert(ch, str[i].length());

            }

            s = cin.nextLine();

            ch = s.toCharArray();

            for (i = 0; i < s.length(); i++) {

                temp = judge(ch[i]);

                if (temp == 0)

                    a++;

                else if (temp == 1)

                    b++;

                else if (temp == 2)

                    c++;

                else

                    d++;

            }

            build_ac();

            int dp[][][][][] = new int[a + 1][b + 1][c + 1][d + 1][t + 1];

            for (i = 0; i <= a; i++) {

                for (j = 0; j <= b; j++) {

                    for (k = 0; k <= c; k++) {

                        for (u = 0; u <= d; u++) {

                            for (v = 0; v <= t; v++)

                                dp[i][j][k][u][v] = -1;

                        }

                    }

                }

            }

            dp[0][0][0][0][0] = 0;

            for (i = 0; i < a + b + c + d; i++) {

                for (j = 0; j <= a; j++) {

                    for (k = 0; k <= b; k++) {

                        for (u = 0; u <= c; u++) {

                            for (v = 0; v <= d; v++) {

                                if (j + k + u + v != i)

                                    continue;

                                for (w = 0; w < t; w++) {

                                    if (dp[j][k][u][v][w] == -1)

                                        continue;

                                    for (x = 0; x < 4; x++) {

                                        if (x == 0 && j + 1 <= a) {

                                            if (dp[j + 1][k][u][v][trie[w][x]] < dp[j][k][u][v][w]

                                                    + o[trie[w][x]])

                                                dp[j + 1][k][u][v][trie[w][x]] = dp[j][k][u][v][w]

                                                        + o[trie[w][x]];

                                        } else if (x == 1 && k + 1 <= b) {

                                            if (dp[j][k + 1][u][v][trie[w][x]] < dp[j][k][u][v][w]

                                                    + o[trie[w][x]])

                                                dp[j][k + 1][u][v][trie[w][x]] = dp[j][k][u][v][w]

                                                        + o[trie[w][x]];

                                        } else if (x == 2 && u + 1 <= c) {

                                            if (dp[j][k][u + 1][v][trie[w][x]] < dp[j][k][u][v][w]

                                                    + o[trie[w][x]])

                                                dp[j][k][u + 1][v][trie[w][x]] = dp[j][k][u][v][w]

                                                        + o[trie[w][x]];

                                        } else if (x == 3 && v + 1 <= d) {

                                            if (dp[j][k][u][v + 1][trie[w][x]] < dp[j][k][u][v][w]

                                                    + o[trie[w][x]])

                                                dp[j][k][u][v + 1][trie[w][x]] = dp[j][k][u][v][w]

                                                        + o[trie[w][x]];

                                        }

                                    }

                                }

                            }

                        }

                    }

                }

            }

            int ans = 0;

            for (i = 0; i < t; i++) {

                if (ans < dp[a][b][c][d][i])

                    ans = dp[a][b][c][d][i];

            }

            System.out.println("Case " + cas + ": " + ans);

            cas++;

        }

    }

}
View Code

 HDU 3247 Resource Archiver

只有最后一个状态有关。

#include <iostream>

#include <cstdio>

#include <string>

#include <map>

#include <algorithm>

#include <cstring>

#include <queue>

using namespace std;

#define N 60001

#define INF 0x3f3f3f3f

char str[10001];

int trie[60001][2];

int fail[60001];

int flag[60001];

int o[60001];

int in[60001];

int que[60001];

int dis[60001];

int t,n;

int dp[1024][11];

int end[11];

int mp[11][11];

void CL()

{

    memset(o,0,sizeof(o));

    memset(flag,0,sizeof(flag));

    memset(trie,-1,sizeof(trie));

    memset(dp,0,sizeof(dp));

    t = 1;

}

void insert(char *s,int x)

{

    int root,len,i;

    len = strlen(s);

    root = 0;

    for(i = 0; i < len; i ++)

    {

        if(trie[root][s[i]-'0'] == -1)

            trie[root][s[i]-'0'] = t ++;

        root = trie[root][s[i]-'0'];

    }

    if(x == -1)

    {

        o[root] = 1;

    }

    else

    {

        flag[root] |= 1<<x;

        end[x+1] = root;

    }

}

void build_ac()

{

    int head,tail,i,front;

    head = tail = 0;

    for(i = 0; i < 2; i ++)

    {

        if(trie[0][i] != -1)

        {

            que[tail++] = trie[0][i];

            fail[trie[0][i]] = 0;

        }

        else

        {

            trie[0][i] = 0;

        }

    }

    while(head != tail)

    {

        front = que[head++];

        o[front] |= o[fail[front]];

        flag[front] |= flag[fail[front]];

        for(i = 0; i < 2; i ++)

        {

            if(trie[front][i] != -1)

            {

                que[tail++] = trie[front][i];

                fail[trie[front][i]] = trie[fail[front]][i];

            }

            else

            {

                trie[front][i] = trie[fail[front]][i];

            }

        }

    }

}

void spfa(int x)

{

    int i,u;

    for(i = 0; i < t; i ++)

    {

        dis[i] = INF;

        in[i] = 0;

    }

    dis[end[x]] = 0;

    queue<int> que;

    que.push(end[x]);

    while(!que.empty())

    {

        u = que.front();

        in[u] = 0;

        que.pop();

        for(i = 0; i < 2; i ++)

        {

            if(o[trie[u][i]]) continue;

            if(dis[trie[u][i]] > dis[u] + 1)

            {

                dis[trie[u][i]] = dis[u] + 1;

                if(in[trie[u][i]] == 0)

                {

                    in[trie[u][i]] = 1;

                    que.push(trie[u][i]);

                }

            }

        }

    }

    for(i = 0; i < n; i ++)

        mp[x][i] = dis[end[i]];

}

int main()

{

    int m,i,j,k;

    while(scanf("%d%d",&n,&m)!=EOF)

    {

        if(n == 0&&m == 0) break;

        CL();

        for(i = 0; i < n; i ++)

        {

            scanf("%s",str);

            insert(str,i);

        }

        for(i = 0; i < m; i ++)

        {

            scanf("%s",str);

            insert(str,-1);

        }

        build_ac();

        n ++;

        for(i = 0; i < n; i ++)

        {

            spfa(i);

        }

        memset(dp,127,sizeof(dp));

        dp[0][0] = 0;

        for(i = 0; i < 1<<(n-1); i ++)

        {

            for(j = 0; j < n; j ++)

            {

                for(k = 0; k < n; k ++)

                {

                    if(mp[j][k] == INF) continue;

                    dp[i|flag[end[k]]][k] = min(dp[i|flag[end[k]]][k],dp[i][j]+mp[j][k]);

                }

            }

        }

        int ans = INF;

        for(i = 0; i < n; i ++)

        {

            ans = min(dp[(1<<(n-1))-1][i],ans);

        }

        printf("%d\n",ans);

    }

    return 0;

}
View Code

ZOJ 3494 BCD Code

数位DP+AC自动机,写错好几个地方,然后...各种wa很棒的一题...

#include <iostream>

#include <cstdio>

#include <string>

#include <map>

#include <algorithm>

#include <cstring>

#include <queue>

using namespace std;

#define MOD 1000000009

#define LL long long

int flag[11][4];

int num[301];

int trie[5001][2];

int fail[5001];

int o[5001];

int que[5001];

int dp[201][5001];

int t,slen;

void CL()

{

    memset(o,0,sizeof(o));

    memset(trie,-1,sizeof(trie));

    t = 1;

}

void insert(char *s)

{

    int root,len,i;

    len = strlen(s);

    root = 0;

    for(i = 0; i < len; i ++)

    {

        if(trie[root][s[i]-'0'] == -1)

            trie[root][s[i]-'0'] = t ++;

        root = trie[root][s[i]-'0'];

    }

    o[root] = 1;

}

void build_ac()

{

    int head,tail,i,front;

    head = tail = 0;

    for(i = 0; i < 2; i ++)

    {

        if(trie[0][i] != -1)

        {

            que[tail++] = trie[0][i];

            fail[trie[0][i]] = 0;

        }

        else

        {

            trie[0][i] = 0;

        }

    }

    while(head != tail)

    {

        front = que[head++];

        o[front] |= o[fail[front]];

        for(i = 0; i < 2; i ++)

        {

            if(trie[front][i] != -1)

            {

                que[tail++] = trie[front][i];

                fail[trie[front][i]] = trie[fail[front]][i];

            }

            else

            {

                trie[front][i] = trie[fail[front]][i];

            }

        }

    }

}

void fun(char *s)

{

    int i,len;

    len = strlen(s);

    s[len-1] --;

    for(i = len-1;i >= 0;i --)

    {

        if(s[i] < '0')

        {

            s[i] += 10;

            s[i-1] --;

        }

    }

}

LL dfs(int pos,int pre,int pix,int bound)

{

    LL ans = 0;

    int i,j,end,z,root;

    if(pos == slen) return 1;

    if(!pix&&!bound&&dp[pos][pre] != -1)

    return dp[pos][pre];

    end = bound ? num[pos]:9;

    for(i = 0;i <= end;i ++)

    {

        z = 0;

        root = pre;

        for(j = 0;j < 4;j ++)

        {

            root = trie[root][flag[i][j]];

            if(o[root]) z = 1;

        }

        if(pix&&i == 0&&pos != slen-1)

        {

            ans += dfs(pos+1,0,1,(i == end)&&bound);

            ans %= MOD;

            continue;

        }

        if(z) continue;

        ans += dfs(pos+1,root,0,(i == end)&&bound);

        ans %= MOD;

    }

    if(!bound)

    dp[pos][pre] = ans;

    return ans%MOD;

}

LL judge(char *s)

{

    int len = strlen(s),i;

    memset(dp,-1,sizeof(dp));

    slen = len;

    for(i = len-1;i >= 0;i --)

    num[i] = s[i] - '0';

    return dfs(0,0,1,1);

}

int main()

{

    int t,i,j,n;

    char str[201];

    char x[201],y[201];

    for(i = 0;i < 10;i ++)

    {

        for(j = 0;j < 4;j ++)

        {

            if(i&(1<<j))

            flag[i][3-j] = 1;

            else

            flag[i][3-j] = 0;

        }

    }

    scanf("%d",&t);

    while(t--)

    {

        CL();

        scanf("%d",&n);

        for(i = 0;i < n;i ++)

        {

            scanf("%s",str);

            insert(str);

        }

        build_ac();

        scanf("%s%s",x,y);

        fun(x);

        LL ans = (judge(y) - judge(x))%MOD;

        if(ans < 0)

        ans += MOD;

        printf("%lld\n",ans);

    }

    return 0;

}
View Code

 

 

你可能感兴趣的:(AC自动机)