• 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
    ",ans);
            }
            printf("
    ");
        }
        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("
    ");
                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("
    ");
        }
        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
    ",cas++);
            for(i = 1; i <= n; i ++)
                printf("%d
    ",*ans[i]);
            printf("
    ");
        }
        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!
    ");
            else
            printf("%.2lf
    ",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
    ",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
    ",ans);
        }
        return 0;
    }
    View Code

     

  • 相关阅读:
    一、JDBC操作
    十五、时间日期类
    十四、字符串详解
    源文件
    十六、·实现显示所有雇员
    十五、抽象出基础接口
    十四、增加EmployeeService实现用户添加
    十三、解决懒加载
    python __new__以及__init__
    Python的getattr(),setattr(),delattr(),hasattr()及类内建__getattr__应用
  • 原文地址:https://www.cnblogs.com/naix-x/p/3728752.html
Copyright © 2020-2023  润新知