• poj 2778 DNA Sequence 夜


    http://poj.org/problem?id=2778

    AC自动机 + 矩阵连乘

    代码:

    #include<iostream>
    #include<cmath>
    #include<cstdio>
    #include<string>
    #include<cstring>
    #include<vector>
    #include<stack>
    #include<queue>
    #include<set>
    #include<map>
    #include<algorithm>
    
    #define LL long long
    
    using namespace std;
    
    const int INF=0x3f3f3f3f;
    const int MOD=100000;
    const LL LMOD=100000;
    const int N=1005;
    const int M=1005;
    const int K=4;
    const int MATRIXN=5;
    const int MATRIXM=115;
    const int MATRIXH=115;
    struct nodeTrie
    {
        int v;
        int fail;
        int next[K];
        void initialize()
        {
            v=0;
            fail=-1;
            memset(next,-1,sizeof(next));
        }
    }trie[M];
    int cnt,root;
    char s[N];
    LL ma[MATRIXN][MATRIXM],mb[MATRIXM][MATRIXH],mc[MATRIXM][MATRIXH];
    int getNewNode()
    {
        ++cnt;
        trie[cnt].initialize();
        return cnt;
    }
    void addWord(int p,char *s,int k)
    {
        if(s[0]=='\0') return ;
        for(int i=0;s[i]!='\0';++i)
        {
            if(trie[p].next[s[i]-'A']==-1)
            trie[p].next[s[i]-'A']=getNewNode();
            p=trie[p].next[s[i]-'A'];
        }
        (trie[p].v)=k;
    }
    void init(int n)
    {
        cnt=0;
        root=getNewNode();
        for(int i=0;i<4;++i)
        {
            s[0]='A'+i;s[1]='\0';
            addWord(root,s,0);
        }
        while(n--)
        {
            gets(s);
            for(int i=0;s[i]!='\0';++i)
            {
                if(s[i]=='C')
                s[i]='B';
                else if(s[i]=='G')
                s[i]='C';
                else if(s[i]=='T')
                s[i]='D';
            }
            addWord(root,s,1);
        }
    }
    void bfs(int p)
    {
        trie[p].fail=root;
        queue<int>qt;
        qt.push(p);
        while(!qt.empty())
        {
            int y;
            int x=qt.front();qt.pop();
            for(int i=0;i<K;++i)
            if(trie[x].next[i]!=-1)
            {
                qt.push(trie[x].next[i]);
                if(x==root)
                {trie[trie[x].next[i]].fail=root;continue;}
                y=trie[x].fail;
                while(y!=root&&trie[y].next[i]==-1)
                y=trie[y].fail;
                if(trie[y].next[i]!=-1)
                trie[trie[x].next[i]].fail=trie[y].next[i];
                else
                trie[trie[x].next[i]].fail=root;
            }
        }
    }
    void makeMatrix(LL a[][MATRIXM],int n)
    {
        for(int i=1;i<=n;++i)
        for(int j=1;j<=n;++j)
        a[i][j]=0;
        for(int i=1;i<=n;++i)
        for(int j=0;j<4;++j)
        {//cout<<i<<endl;
            int p=i;
            int q=0;
            while(p!=root&&trie[p].next[j]==-1)
            p=trie[p].fail;
            if(trie[p].next[j]!=-1)
            q=trie[p].next[j];
            int w=q;
            bool flag=true;
            while(w!=root)
            {
                if(trie[w].v>0)
                {flag=false;break;}
                w=trie[w].fail;
            }
            if(trie[w].v>0)
            flag=false;
            if(flag==true)
            a[i][q]=1;
        }
    }
    void matrixMul(LL a[][MATRIXM],LL b[][MATRIXM],int n,int m,int h)
    {
        for(int i=1;i<=n;++i)
        for(int j=1;j<=h;++j)
        {
            LL tmp=0;
            for(int l=1;l<=m;++l)
            tmp=(tmp+a[i][l]*b[l][j])%LMOD;
            mc[i][j]=tmp;
        }
        for(int i=1;i<=n;++i)
        for(int j=1;j<=h;++j)
        a[i][j]=mc[i][j];
    }
    int main()
    {
        //freopen("data.in","r",stdin);
        int n,m;
        while(scanf("%d %d ",&n,&m)!=EOF)
        {
            init(n);
            bfs(root);
            int MN=1,MM=cnt,MH=cnt;
            makeMatrix(mb,MM);
            memset(ma,0,sizeof(ma));
            ma[1][1]=1;
            while(m>0)
            {
                if((m&1)==1)
                matrixMul(ma,mb,MN,MM,MH);
                matrixMul(mb,mb,MM,MM,MH);
                m=(m>>1);
            }
            LL ans=0;
            for(int i=1;i<=MN;++i)
            for(int j=1;j<=MM;++j)
            ans=(ans+ma[i][j])%LMOD;
            cout<<ans<<endl;
        }
        return 0;
    }
    

      

  • 相关阅读:
    【JZOJ4803】求导【模拟】
    【洛谷P1972】【BZOJ1878】HH的项链【莫队】
    【洛谷P1972】【BZOJ1878】HH的项链【莫队】
    【洛谷P1631】序列合并【堆】
    【洛谷P1631】序列合并【堆】
    【洛谷P1903】【BZOJ2120】数颜色 / 维护队列【带修莫队】
    【洛谷P1484】种树【堆】【贪心】
    【洛谷P1484】种树【堆】【贪心】
    【JZOJ4802】探险计划【费用流】
    【JZOJ4802】探险计划【费用流】
  • 原文地址:https://www.cnblogs.com/liulangye/p/2976801.html
Copyright © 2020-2023  润新知