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

 

 

posted @ 2014-05-14 21:48  Naix_x  阅读(255)  评论(0编辑  收藏  举报