zoukankan      html  css  js  c++  java
  • 考研路茫茫--单词情结

    分析:与poj的2778差不多的,求出来所有的情况然后减去不包含的就行了,这次使用了一下kuangbin的那种自动机写法,确实还不错,因为尤是在建立矩阵的时候更加方便。

     
    代码如下:
    ===============================================================================================================================
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<queue>
    #include<iostream>
    using namespace std;
    
    const int MAXN = 107;
    const int MAXM = 26;
    const int mod  = 100000;
    
    struct Matrix
    {///定义矩阵
        int size;
        unsigned long long edge[MAXN][MAXN];
    
        Matrix(int Len)
        {
            size = Len;
            memset(edge, false, sizeof(edge));
        }
        Matrix operator *(const Matrix &Map) const
        {
            Matrix ans(size);
    
            for(int i=0; i<size; i++)
            for(int j=0; j<size; j++)
            for(int k=0; k<size; k++)
            {
                ans.edge[i][j] += edge[i][k] * Map.edge[k][j];
            }
    
            return ans;
        }
    };
    
    struct Ac_Trie
    {
        int next[MAXN][MAXM];
        int fail[MAXN], End[MAXN];
        int Len, root;
    
        Ac_Trie()
        {
            memset(next, -1, sizeof(next));
            memset(End, false, sizeof(End));
            Len = 1, root = 0;
        }
    
        void Insert(char s[])
        {
            int p = root;
    
            for(int i=0; s[i]; i++)
            {
                int k = s[i] - 'a';
    
                if(next[p][k] == -1)
                    next[p][k] = Len++;
                p = next[p][k];
            }
    
            End[p] = true;
        }
    
        void GetFail()
        {
            queue<int> Q;
            int p = root;
    
            fail[p] = root;
    
            for(int i=0; i<MAXM; i++)
            {
                if(next[p][i] == -1)
                    next[p][i] = root;
                else
                {
                    fail[next[p][i]] = root;
                    Q.push(next[p][i]);
                }
            }
    
            while(Q.size())
            {
                p = Q.front();
                Q.pop();
    
                for(int i=0; i<MAXM; i++)
                {
                    if(next[p][i] == -1)
                        next[p][i] = next[fail[p]][i];
                    else
                    {
                        fail[next[p][i]] = next[fail[p]][i];
                        Q.push(next[p][i]);
                    }
                }
    
                End[p] |= End[fail[p]];
            }
        }
    
        Matrix GetMatrix()
        {
            Matrix ans(Len+1);
    
            for(int i=0; i<Len; i++)
            for(int k=0; k<MAXM; k++)
            {
                if(End[next[i][k]] == false)
                    ans.edge[i][next[i][k]] += 1;
            }
    
            for(int i=0; i<=Len; i++)
                ans.edge[i][Len] = 1;
    
            return ans;
        }
    };
    
    Matrix QuickPow(long long K, Matrix Map)
    {
        Matrix ans(Map.size);
    
        for(int i=0; i<ans.size; i++)
            ans.edge[i][i] = 1;
    
        while(K)
        {
            if(K & 1)
                ans = ans * Map;
            Map = Map * Map;
    
            K /= 2;
        }
    
        return ans;
    }
    
    int main()
    {
        long long N, L;
    
        while(scanf("%lld%lld", &N, &L) != EOF)
        {
            char s[MAXN];
            Ac_Trie a;
    
            while(N--)
            {
                scanf("%s", s);
                a.Insert(s);
            }
    
            a.GetFail();
            Matrix ans = a.GetMatrix();
    
            unsigned long long sum1=0, sum=0;
    
            ans = QuickPow(L, ans);
    
            for(int i=0; i<ans.size; i++)
                sum1 += ans.edge[0][i];
    
            ans.size = 2;
            ans.edge[0][0] = 26;
            ans.edge[1][0] = 0;
            ans.edge[0][1] = ans.edge[1][1] = 1;
    
            ans = QuickPow(L, ans);
    
            sum = ans.edge[0][1] + ans.edge[0][0];
    
            cout << sum - sum1 <<endl;
        }
    
        return 0;
    }
  • 相关阅读:
    阿里云HPC助力新制造 | 上汽仿真计算云SSCC
    阿里云数据库备份DBS商业化发布,数据库实时备份到OSS
    一张图读懂数据库备份
    数据库智能管理助手-CloudDBA
    重新定义数据库的时刻,阿里云数据库专家带你了解POLARDB
    时间序列数据的处理
    【大量干货】史上最完整的Tengine HTTPS原理解析、实践与调试
    ECS主动运维事件--让你HOLD住全场 (二)
    【52.49%】【codeforces 556A】Case of the Zeros and Ones
    【66.47%】【codeforces 556B】Case of Fake Numbers
  • 原文地址:https://www.cnblogs.com/liuxin13/p/4754995.html
Copyright © 2011-2022 走看看