zoukankan      html  css  js  c++  java
  • spoj 1676 AC自动机+矩阵快速

    Time Limit: 1386MS   Memory Limit: 1572864KB   64bit IO Format: %lld & %llu

     Status

    Description

    LoadingTime has been given a task these days. He is required to write a tool called Text Generator. This software is widely used among the kids who are under seven. It generates an article with the size of a given number L for users. If an article contains at least one word which the users know, we consider it readable. Now, LoadingTime wants to know, how many readable articles can it generates, and he can improve his Text Generator. Could you help him??

    Input

    The input contains multiple test cases.

    The first line of each test case contains two integer N (1 <= N <= 10), L (1 <= L <= 1000000). The following N lines contain N words representing the words knew by the users. All the words and the generated article only contain uppercase letters, and the length of each word is not greater than 6.

    Output

    For each test case, your program should output a integer as LoadingTime required. As the number could be quite large, you only need to print the answer modulo 10007.

    Example

    Input:
    2 2
    A
    B
    2 10000
    ABC
    B
    
    Output:
    100
    5960
    /*
    spoj 1676 AC自动机+矩阵快速
    
    给你m个串,求包含任意个数这些串的长度为n的字符串的种类
    通过AC自动+矩阵可以快速求出不包含这些串的种类数。  再用快速幂求出总的可能数然后减去
    这些即可
    
    hhh-2016-04-23 20:20:22
    */
    #include <iostream>
    #include <vector>
    #include <cstring>
    #include <string>
    #include <cstdio>
    #include <queue>
    #include <functional>
    #include <map>
    using namespace std;
    #define lson  (i<<1)
    #define rson  ((i<<1)|1)
    typedef long long ll;
    typedef unsigned int ul;
    const int  maxn = 40010;
    const int mod = 10007;
    struct Matrix
    {
        int len;
        ul ma[70][70];
        Matrix() {}
        Matrix(int L)
        {
            len = L;
        }
    };
    
    Matrix mult(Matrix ta,Matrix tb)
    {
        Matrix tc;
        tc.len = ta.len;
        for(int i = 0; i < ta.len; i++)
        {
            for(int j = 0; j < ta.len; j++)
            {
                tc.ma[i][j] = 0;
                for(int k = 0; k < ta.len; k++){
                    tc.ma[i][j] = tc.ma[i][j]+ta.ma[i][k]*tb.ma[k][j];
                }
                tc.ma[i][j] %= mod;
            }
        }
        return tc;
    }
    
    Matrix pow_mat(Matrix a,int n)
    {
        Matrix cnt = a;
        n--;
        while(n)
        {
            if(n&1) cnt = mult(cnt,a);
            a = mult(a,a);
            n >>= 1;
        }
        return cnt;
    }
    
    struct Tire
    {
        int nex[70][30],fail[70],ed[70];
        int root,L;
        int newnode()
        {
            for(int i = 0; i < 26; i++)
                nex[L][i] = -1;
            ed[L++] = 0;
            return L-1;
        }
    
        void ini()
        {
            L = 0,root = newnode();
        }
    
        void inser(char buf[])
        {
            int len = strlen(buf);
            int now = root;
            for(int i = 0; i < len; i++)
            {
                int ta = buf[i]-'A';
                if(nex[now][ta] == -1)
                    nex[now][ta] = newnode();
                now = nex[now][ta];
            }
            ed[now]++;
        }
    
        void build()
        {
            queue<int >q;
            fail[root] = root;
            for(int i = 0; i < 26; i++)
                if(nex[root][i] == -1)
                    nex[root][i] = root;
                else
                {
                    fail[nex[root][i]] = root;
                    q.push(nex[root][i]);
                }
            while(!q.empty())
            {
                int now = q.front();
                if(ed[fail[now]])
                    ed[now] = 1;
                q.pop();
                for(int i = 0; i < 26; i++)
                {
                    if(nex[now][i] == -1)
                        nex[now][i] = nex[fail[now]][i];
                    else
                    {
                        fail[nex[now][i]] = nex[fail[now]][i];
                        q.push(nex[now][i]);
                    }
                }
            }
        }
    
        Matrix to_mat()
        {
            Matrix mat(L);
            memset(mat.ma,0,sizeof(mat.ma));
    
            for(int i = 0;i < L;i++)
            {
                for(int j = 0;j < 26;j++)
                {
                    if(!ed[nex[i][j]])
                        mat.ma[i][nex[i][j]]++;
                }
            }
            return mat;
        }
    };
    
    int pow_mod(int a,int n)
    {
        a%=mod;
        int cnt = 1;
        while(n)
        {
            if(n&1) cnt =cnt*a%mod;
            a = a*a%mod;
            n >>= 1;
        }
        return cnt;
    }
    
    Tire ac;
    char buf[20];
    int main()
    {
        int m;
        int n;
        while(scanf("%d%d",&m,&n) != EOF)
        {
            ac.ini();
            for(int i = 0; i < m; i++)
            {
                scanf("%s",buf);
                ac.inser(buf);
            }
            ac.build();
            Matrix ta = ac.to_mat();
            int ans = 0;
            ta = pow_mat(ta,n);
            for(int i = 0;i < ta.len;i++)
            {
                ans = ans+(int)ta.ma[0][i];
            }
            ans = pow_mod(26,n)-ans;
            while(ans < 0)
                ans += mod;
            printf("%d
    ",ans%mod);
        }
        return 0;
    }
    

      

  • 相关阅读:
    linux查看端口
    linux下Git代码
    linux安装mysql
    pip工具更新及解决"No module named pip"问题
    demo-bootstrap实现滑动开关
    vue 随笔
    css 解决盒子移动鼠标丢失产生的抖动问题
    笔记-纯css实现select的placeholder
    笔记-移动端rem适配和解决安卓手机键盘唤起引起样式问题
    demo-tab切换
  • 原文地址:https://www.cnblogs.com/Przz/p/5449117.html
Copyright © 2011-2022 走看看