zoukankan      html  css  js  c++  java
  • HDU 2243 AC自动机

    题目链接 

    http://acm.hdu.edu.cn/showproblem.php?pid=2243
    

      

    题目大意:字母表为a~z,给n=5个词根,问长度不超过L=2^32的单词(不要问为什么有这么长的单词,就是有这么长)至少包含一个词根有多少个?

    把长度为不超过L的单词数和加起来,再减去一个词根都不包含的数量。一个词根都不包含的数量的求法跟上题相同。

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <cctype>
    #include <vector>
    #include <bitset>
    #include <stack>
    #include <queue>
    #include <map>
    #include <algorithm>
    #include <iostream>
    #include <string>
    #include <set>
    #define X first
    #define Y second
    #define sqr(x) (x)*(x)
    #pragma comment(linker,"/STACK:102400000,102400000")
    using namespace std;
    const double PI = acos(-1.0);
    map<int, int>::iterator it;
    typedef long long LL ;
    typedef unsigned long long uLL;
    template<typename T> void checkmin(T &x, T y) {x = min(x, y);}
    template<typename T> void checkmax(T &x, T y) {x = max(x, y);}
    
    const int MAX_NODE = 26;
    const int CHILD_NUM = 26;
    
    class Matrix {
        public:
            uLL d[MAX_NODE][MAX_NODE];
            int m;
            Matrix() {}
            Matrix(int _m): m(_m) {};
            void Set_Zero() {
                memset(d, 0, sizeof(d));
            }
            void Set_One() {
                Set_Zero();
                for(int i = 0; i < m; ++i)d[i][i] = 1;
            }
            Matrix operator +(Matrix a) {
                Matrix ret(m);
                for(int i = 0; i < m; ++i)for(int j = 0; j < m; ++j)ret.d[i][j] = d[i][j] + a.d[i][j];
                return ret;
            }
            Matrix operator *(Matrix a) {
                Matrix ret(m);
                ret.Set_Zero();
                for(int i = 0; i < m; ++i) {
                    for(int k = 0; k < m; ++k) {
                        if(d[i][k] == 0)continue;
                        for(int j = 0; j < m; ++j) {
                            ret.d[i][j] += d[i][k] * a.d[k][j];
                        }
                    }
                }
                return ret;
            }
            Matrix Power(LL n) {
                Matrix a(m), b(m);
                a = *this;
                b.Set_One();
                while(n) {
                    if(n & 1)b = b * a;
                    a = a * a;
                    n >>= 1;
                }
                return b;
            }
            Matrix Get_Psum(LL n) {
                Matrix ret;
                if(n == 1)return *this;
                if(n & 1) {
                    ret = Get_Psum(n / 2);
                    ret = ret + ret * Power(n / 2) + Power(n);
                }
                else {
                    ret = Get_Psum(n / 2);
                    ret = ret + ret * Power(n / 2);
                }
                return ret;
            }
            void pf() {
                for(int i = 0; i < m; ++i) {
                    for(int j = 0; j < m; ++j) {
                        printf("%3d", d[i][j]);
                    } puts("");
                }
            }
    };
    
    class ACAutomaton {
        public:
            int chd[MAX_NODE][CHILD_NUM];
            int val[MAX_NODE];
            int ID[126];
            int Q[MAX_NODE];
            int fail[MAX_NODE];
            int sz;
            void Initialize() {
                fail[0] = 0;
                for(int i = 0; i < 26; ++i) {
                    ID['a'+i] = i;
                }
            }
            void Reset() {
                sz = 1;
                memset(chd[0], -1, sizeof(chd[0]));
            }
            void Insert(char *s) {
                int q = 0;
                for(; *s; ++s) {
                    int c = ID[*s];
                    if(chd[q][c] == -1) {
                        memset(chd[sz], -1, sizeof(chd[sz]));
                        val[sz] = 0;
                        chd[q][c] = sz++;
                    }
                    q = chd[q][c];
                }
                val[q] = 1;
            }
            void Construct() {
                int *s = Q, *e = Q;
                for(int i = 0; i < CHILD_NUM; ++i) {
                    if(~chd[0][i]) {
                        fail[ chd[0][i] ] = 0;
                        *s++ = chd[0][i];
                    }
                    else chd[0][i] = 0;
                }
                while(s != e) {
                    int r = *e++;
                    for(int i = 0; i < CHILD_NUM; ++i) {
                        int &u = chd[r][i];
                        int v = fail[r];
                        if(~u) {
                            *s++ = u;
                            fail[u] = chd[v][i];
                            val[u] |= val[ fail[u] ];
                        }
                        else u = chd[v][i];
                    }
                }
            }
            Matrix Get_Matrix() {
                Matrix ret(sz);
                ret.Set_Zero();
                for(int i = 0; i < sz; ++i) {
                    if(val[i])continue;
                    for(int j = 0; j < CHILD_NUM; ++j) {
                        if(val[ chd[i][j] ])continue;
                        ++ret.d[i][ chd[i][j] ];
                    }
                }
                return ret;
            }
    } AC;
    const uLL K = 26;
    
    uLL Power(uLL x, LL n) {
        uLL a = x, b = 1;
        while(n) {
            if(n & 1)b *= a;
            a *= a;
            n >>= 1;
        }
        return b;
    }
    
    uLL Get_PS(LL n) {
        //cout<<n<<endl;
        if(n == 1)return K;
        uLL ret, a, b;
        if(n & 1) {
            ret = Get_PS(n / 2);
            ret = ret + ret * Power(K, n / 2) + Power(K, n);
        }
        else {
            ret = Get_PS(n / 2);
            ret = ret + ret * Power(K, n / 2);
        }
        return ret;
    }
    
    char s[7];
    int main() {
        int n;
        uLL L;
        AC.Initialize();
        while(~scanf("%d%I64u", &n, &L)) {
            uLL sum = 0;
            uLL e = 1;
            AC.Reset();
            sum = Get_PS(L);
            //printf("%I64u
    ",sum);
            for(uLL i = 0; i < n; ++i) {
                scanf("%s", s);
                AC.Insert(s);
            }
            AC.Construct();
            Matrix a = AC.Get_Matrix();
            //a.pf();
            Matrix b = a.Get_Psum(L) ;
            uLL res = 0;
            for(int j = 0; j < b.m; ++j) {
                res += b.d[0][j];
            }
            res = sum - res;
            printf("%I64u
    ", res);
        }
        return 0;
    }
    

      

  • 相关阅读:
    SpringMVC @RequestBody请求参数在postman中的请求
    git rm -r --cached 去掉已经托管在git上的文件
    shiro源码解析--------欢迎指出错误地方,还有一起讨论一下ShiroFilterFactoryBean配置过滤URL规则
    如何用Tomcat部署前端静态文件
    用HTML 格式导出Excel
    csv和excel的区别
    使用HttpOnly提升Cookie安全性
    asp.net core 如何在Controller获取配置文件的值
    Find Out What Your Entity Framework Query Is Really Doing
    鸡汤
  • 原文地址:https://www.cnblogs.com/cxw199204/p/3401165.html
Copyright © 2011-2022 走看看