• HDU 2243 考研路茫茫——单词情结(AC自动机+DP+快速幂)


    题目链接

    错的上头了...

    这题是DNA的加强版,26^1 +26^2... - A^1-A^2...

    先去学了矩阵的等比数列求和,学的是第二种方法,扩大矩阵的方法。剩下就是各种模板,各种套。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <map>
    #include <algorithm>
    #include <vector>
    #include <string>
    using namespace std;
    #define LL unsigned __int64
    #define N 100001
    int t,trie[N][26],que[N],o[N],fail[N];
    LL p[201][201],mat[201][201];
    void CL()
    {
        memset(trie,-1,sizeof(trie));
        memset(p,0,sizeof(p));
        memset(o,0,sizeof(o));
        t = 1;
    }
    void insert(char *s)
    {
        int i,root,len;
        len = strlen(s);
        root = 0;
        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] = 1;
    }
    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++];
            if(o[fail[front]])
                o[front] = 1;
            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 work()
    {
        int i,j;
        for(i = 0; i < t; i ++)
        {
            if(o[i]) continue;
            for(j = 0; j < 26; j ++)
            {
                if(o[trie[i][j]]) continue;
                p[i][trie[i][j]] ++;
            }
        }
        for(i = 0; i < t; i ++)
        {
            p[i][t+i] = p[t+i][t+i] = 1;
        }
        t <<= 1;
    }
    LL qmod(LL n)
    {
        int i,j,k;
        LL c[201][201],ans = 0;
        while(n)
        {
            if(n&1)
            {
                memset(c,0,sizeof(c));
                for(i = 0; i < t; i ++)
                {
                    for(j = 0; j < t; j ++)
                    {
                        for(k = 0; k < t; k ++)
                        {
                            c[i][j] += mat[i][k]*p[k][j];
                        }
                    }
                }
                memcpy(mat,c,sizeof(mat));
            }
            memset(c,0,sizeof(c));
            for(i = 0; i < t; i ++)
            {
                for(j = 0; j < t; j ++)
                {
                    for(k = 0; k < t; k ++)
                    {
                        c[i][j] += p[i][k]*p[k][j];
                    }
                }
            }
            memcpy(p,c,sizeof(p));
            n >>= 1;
        }
        for(i = t/2; i < t; i ++)
        {
            ans += mat[0][i];
        }
        return ans-1;
    }
    
    LL fastmod(LL a,LL k)
    {
        LL b = 1;
        while(k)
        {
            if(k&1)
                b = a*b;
            a = a*a;
            k = k/2;
        }
        return b;
    }
    LL getnum(LL p,LL k)
    {
        if (k <= 0) return 1;
        if (k%2 == 0)
            return ((getnum(p,k/2 - 1))*((1 + fastmod(p,k/2 + 1))) + fastmod(p,k/2));
        else
            return ((getnum(p,(k + 1)/2 - 1))*((1 + fastmod(p,(k + 1)/2))));
    }
    int main()
    {
        int i,j,m;
        LL n;
        char ch[101];
        while(scanf("%d%I64u",&m,&n)!=EOF)
        {
            CL();
            for(i = 1; i <= m; i ++)
            {
                scanf("%s",ch);
                insert(ch);
            }
            build_ac();
            work();
            for(i = 0; i < t; i ++)
            {
                for(j = 0; j < t; j ++)
                {
                    mat[i][j] = (i == j);
                }
            }
            printf("%I64u
    ",getnum(26,n)-1-qmod(n+1));
        }
    }
    View Code
  • 相关阅读:
    如何做实时监控?—— 参考 Spring Boot 实现
    如何做实时监控?—— 参考 Spring Boot 实现
    spring boot application properties配置详解
    Jrebel 6.2.1破解
    智能社-JS -wiki
    hibernate.properties
    Tomcat 的 socket bind failed的解决方法
    js 排序 SORT 各种方法
    java EE 如何使用Eclipse启动一个项目
    2016-06-06 数组的几个重要方法
  • 原文地址:https://www.cnblogs.com/naix-x/p/3712547.html
Copyright © 2020-2023  润新知