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

    好综合的一题啊,AC自动机+DP+非递归矩阵快速幂+二分+逆向思维。

    //#pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<iostream>
    #include<sstream>
    #include<cmath>
    #include<climits>
    #include<string>
    #include<map>
    #include<queue>
    #include<vector>
    #include<stack>
    #include<set>
    using namespace std;
    typedef long long ll;
    typedef unsigned long long ull;
    typedef pair<int,int> pii;
    #define pb(a) push_back(a)
    #define INF 0x1f1f1f1f
    #define lson idx<<1,l,mid
    #define rson idx<<1|1,mid+1,r
    #define PI  3.1415926535898
    template<class T> T min(const T& a,const T& b,const T& c) {
        return min(min(a,b),min(a,c));
    }
    template<class T> T max(const T& a,const T& b,const T& c) {
        return max(max(a,b),max(a,c));
    }
    void debug() {
    #ifdef ONLINE_JUDGE
    #else
    
        freopen("d:\in.txt","r",stdin);
       // freopen("d:\out1.txt","w",stdout);
    #endif
    }
    int getch() {
        int ch;
        while((ch=getchar())!=EOF) {
            if(ch!=' '&&ch!='
    ')return ch;
        }
        return EOF;
    }
    
    const int MAX_NODE=150;
    const int SIGMA_SIZE=26;
    
    
    
    int ch[MAX_NODE][SIGMA_SIZE];
    int fail[MAX_NODE];
    int val[MAX_NODE];
    int sz;
    
    struct Matrix
    {
        ull da[MAX_NODE][MAX_NODE];
        Matrix(){memset(da,0,sizeof(da));}
        Matrix operator * (const Matrix &ans)
        {
            Matrix res;
            for(int i=0;i<sz;i++)
            {
                for(int j=0;j<sz;j++)
                {
                    for(int k=0;k<sz;k++)
                        res.da[i][j]=res.da[i][j]+da[i][k]*ans.da[k][j];
                }
            }
            return res;
        }
        Matrix operator + (const Matrix &ans)
        {
            Matrix res;
            for(int i=0;i<sz;i++)
            {
                for(int j=0;j<sz;j++)
                {
                    res.da[i][j]=da[i][j]+ans.da[i][j];
                }
            }
            return res;
        }
    };
    Matrix base;
    ull pow26[32];
    Matrix powMatrix[32];
    
    int idx(char c)
    {
        return c-'a';
    }
    void init()
    {
        memset(ch[0],0,sizeof(ch[0]));
        val[0]=0;
        sz=1;
    }
    void insert(const char *s)
    {
        int u=0;
        for(int i=0;s[i]!='';i++)
        {
            int v=idx(s[i]);
            if(!ch[u][v])
            {
                memset(ch[sz],0,sizeof(ch[sz]));
                val[sz]=0;
                ch[u][v]=sz++;
            }
            u=ch[u][v];
        }
        val[u]=1;
    }
    
    void construct()
    {
        fail[0]=0;
        queue<int> q;
        for(int c=0;c<SIGMA_SIZE;c++)
            if(ch[0][c]){fail[ch[0][c]]=0;q.push(ch[0][c]);}
        while(!q.empty())
        {
            int r=q.front();q.pop();
            for(int c=0;c<SIGMA_SIZE;c++)
            {
                int u=ch[r][c];
                if(!u){ch[r][c]=ch[fail[r]][c];continue;}
                q.push(u);
                int v=fail[r];
                while(v&&!ch[v][c])v=fail[v];
                fail[u]=ch[v][c];
                val[u]|=val[fail[u]];
            }
        }
    }
    
    void constructMatrix()
    {
        memset(base.da,0,sizeof(base.da));
        for(int u=0;u<sz;u++)if(!val[u])
        {
            for(int c=0;c<SIGMA_SIZE;c++)
            {
                int v=ch[u][c];
                if(!val[v])
                    base.da[u][v]++;
            }
        }
    }
    void initpow(int n)
    {
        int k=31;
        while(!(n&(1<<k)))k--;
        ull x=26;
        Matrix res=base;
        while(k)
        {
            powMatrix[k]=res;
            pow26[k]=x;
            k--;
            if(n&(1<<k))
            {
                x=x*x*26;
                res=res*res*base;
            }else
            {
                x=x*x;
                res=res*res;
            }
        }
        powMatrix[k]=res;
        pow26[k]=x;
    }
    Matrix MatrixSum(int n,int r)
    {
        Matrix res=base;
        int k=31;
        while(!(n&(1<<k)))k--;
        while(k--)
        {
            if(n&(1<<k))
            {
                res=res+res*powMatrix[k+1]+powMatrix[k];
            }else res=res+res*powMatrix[k+1];
        }
        return res;
    }
    
    ull sum(int n,int r)
    {
        if((n>>r)==1)return 26;
        if((n>>r)%2==0)
        {
            ull res=sum(n,r+1);
            return res+res*pow26[r+1];
        }else
        {
            ull res=sum(n,r+1);
            return res+res*pow26[r+1]+pow26[r];
        }
    }
    
    int main()
    {
        int n,m;
        while(scanf("%d%d",&n,&m)!=EOF)
        {
            init();
            for(int i=1;i<=n;i++)
            {
                char s[100];
                scanf("%s",s);
                insert(s);
            }
            construct();
            constructMatrix();
            initpow(m);
            Matrix res=MatrixSum(m,0);
            unsigned long long num=0;
            for(int i=0;i<sz;i++)
                num=num+res.da[0][i];
            ull SUM=sum(m,0);
            printf("%I64u
    ",SUM-num);
        }
        return 0;
    }
    View Code

  • 相关阅读:
    Codeforces 451A Game With Sticks
    POJ 3624 Charm Bracelet
    POJ 2127 Greatest Common Increasing Subsequence
    POJ 1458 Common Subsequence
    HDU 1087 Super Jumping! Jumping! Jumping!
    HDU 1698
    HDU 1754
    POJ 1724
    POJ 1201
    CSUOJ 1256
  • 原文地址:https://www.cnblogs.com/BMan/p/3382735.html
Copyright © 2011-2022 走看看