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;
    }
    

      

  • 相关阅读:
    EF CORE EntityFrameworkCore中关系模式一对一、一对多、多对多的使用
    C# LINQ中Join与GroupJoin的区别
    C#中HttpWebRequest、WebClient、HttpClient的使用
    .Net 性能优化--EFCore(EntityFrameworkCore)
    .Net 性能优化--缓存--分布式缓存
    .Net 性能优化--缓存--http缓存
    .Net 性能优化--缓存--分布式缓存 --sqlserver缓存
    .Net 性能优化--缓存--分布式缓存--reids缓存
    获取Kafka每个分区最新Offset的几种方法
    Wireshark使用入门
  • 原文地址:https://www.cnblogs.com/Przz/p/5449117.html
Copyright © 2011-2022 走看看