• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            poj 2778 DNA Sequence AC自動機+矩陣快速冥

               題意很簡單,假定文本集就是A,C,T,G,給定M個模式串,問你長度為N的文本不出現(xiàn)這些模式
            串的可能性到底有多少種。。。
               確實非常不直觀的樣子。。。
               解法是先學(xué)學(xué)AC自動機,建立起Trie圖,根據(jù)trie圖可以得到長度為1的路徑矩陣,然后再快速
            冥得到長度為N的路徑矩陣。
               說起來都非常糾結(jié),沒學(xué)過AC自動機更加無法理解。學(xué)AC自動機之前據(jù)說得先學(xué)Trie樹和KMP
            才好理解。學(xué)AC自動機搞Trie圖就花費了近2天了,然后弄懂這個題又是一天,好在基本明白了。
               馬上快比賽了,從長春換到金華也不知道是好是壞。。。還是弱菜啊。。。
               貼下我的Trie圖+快速冥(直接二分了,沒有寫成數(shù)論里面那種算法)...

            #include <stdio.h>
            #include <string.h>
            #include <algorithm>
            #include <queue>
            using namespace std;

            typedef long long INT;
            const int MOD = 100000;
            const int MAX_P = 100;
            const int MAX_D = 4;
            int nIdx[256];
            char szPat[MAX_P];
            INT nMatrix[MAX_P][MAX_P];
            INT B[MAX_P][MAX_P];
            INT A[MAX_P][MAX_P];

            void InitIdx()
            {
                nIdx['A'] = 0;
                nIdx['C'] = 1;
                nIdx['T'] = 2;
                nIdx['G'] = 3;
            }

            struct Trie
            {
                Trie* fail;
                Trie* next[MAX_D];
                int no;
                bool flag;
                Trie()
                {
                    fail = NULL;
                    memset(next, 0, sizeof(next));
                    no = 0;
                    flag = false;
                }
            };
            Trie tries[MAX_D * MAX_P];
            int nP;
            Trie* pRoot;

            Trie* NewNode()
            {
                memset(&tries[nP], 0, sizeof(Trie));
                tries[nP].no = nP;
                return &tries[nP++];
            }

            void InitTrie(Trie*& pRoot)
            {
                nP = 0;
                pRoot = NewNode();
            }

            void Insert(char* pszPat)
            {
                Trie* pNode = pRoot;
                
                while (*pszPat)
                {
                    if (pNode->next[nIdx[*pszPat]] == NULL)
                    {
                        pNode->next[nIdx[*pszPat]] = NewNode();
                    }
                    pNode = pNode->next[nIdx[*pszPat]];
                    ++pszPat;
                }
                pNode->flag = true;
            }

            int BuildAC(Trie* pRoot)
            {
                memset(nMatrix, 0, sizeof(nMatrix));
                
                pRoot->fail = NULL;
                queue<Trie*> qt;
                qt.push(pRoot);
                while (!qt.empty())
                {
                    Trie* front = qt.front();
                    qt.pop();
                    
                    for (int i = 0; i < MAX_D; ++i)
                    {
                        if (front->next[i])
                        {
                            Trie* pNode = front->fail;
                            while (pNode && pNode->next[i] == NULL)
                            {
                                pNode = pNode->fail;
                            }
                            front->next[i]->fail = pNode? pNode->next[i] : pRoot;
                            if (front->next[i]->fail->flag == true)
                            {
                                front->next[i]->flag = true;
                            }
                            
                            qt.push(front->next[i]);
                        }
                        else
                        {
                            front->next[i] = front == pRoot? pRoot : front->fail->next[i];
                        }
                        
                        if (front->next[i]->flag == false)
                        {
                            nMatrix[front->no][front->next[i]->no]++;
                        }
                    }
                }
                
                return nP;//節(jié)點總個數(shù)
            }

            void MultyMatrix(INT A[][MAX_P], INT B[][MAX_P], INT C[][MAX_P], int nSize)
            {
                for (int i = 0; i < nSize; ++i)
                {
                    for (int j = 0; j < nSize; ++j)
                    {
                        INT nSum = 0;
                        for (int k = 0; k < nSize; ++k)
                        {
                            nSum = (nSum + A[i][k] * B[k][j]) % MOD;
                        }
                        C[i][j] = nSum;
                    }
                }
            }

            void CopyMatrix(INT A[][MAX_P], INT B[][MAX_P], int nSize)
            {
                for (int i = 0; i < nSize; ++i)
                {
                    for (int j = 0; j < nSize; ++j)
                    {
                        A[i][j] = B[i][j];
                    }
                }
            }

            void MatrixPower(INT M[][MAX_P], int nSize, INT nP)
            {
                if (nP == 1)
                {
                    CopyMatrix(A, M, nSize);
                    return;
                }
                
                MatrixPower(M, nSize, nP / 2);
                MultyMatrix(A, A, B, nSize);
                if (nP % 2)
                {
                    MultyMatrix(B, M, A, nSize);
                }
                else
                {
                    CopyMatrix(A, B, nSize);
                }
            }

            int main()
            {
                INT nM, nN;
                
                InitIdx();
                while (scanf("%I64d%I64d", &nM, &nN) == 2)
                {
                    InitTrie(pRoot);
                    while (nM--)
                    {
                        scanf("%s", szPat);
                        Insert(szPat);
                    }
                    int nSize = BuildAC(pRoot);
                    
                    MatrixPower(nMatrix, nSize, nN);
                    INT nAns = 0;
                    for (int i = 0; i < nSize; ++i)
                    {
                        nAns = (nAns + A[0][i]) % MOD;
                    }
                    printf("%I64d\n", nAns % MOD);
                }
                
                return 0;
            }
               
               

            posted on 2012-10-18 09:46 yx 閱讀(1217) 評論(0)  編輯 收藏 引用 所屬分類: 字符串

            <2012年10月>
            30123456
            78910111213
            14151617181920
            21222324252627
            28293031123
            45678910

            導(dǎo)航

            統(tǒng)計

            公告

            常用鏈接

            留言簿(3)

            隨筆分類

            隨筆檔案

            me

            好友

            同學(xué)

            網(wǎng)友

            搜索

            最新評論

            閱讀排行榜

            評論排行榜

            色狠狠久久综合网| 欧美久久久久久精选9999| 一本久道久久综合狠狠爱| 亚洲色欲久久久综合网东京热| 精品久久久中文字幕人妻| 久久精品无码专区免费青青| 久久综合九色综合久99| 亚洲精品视频久久久| 国内精品久久久久久久97牛牛 | 久久国产一区二区| 国产精品午夜久久| 久久久久久夜精品精品免费啦| 国产福利电影一区二区三区久久老子无码午夜伦不 | 久久人人爽人人爽人人片AV东京热| 久久99精品久久久久久动态图| 99久久精品国产一区二区蜜芽| 国产精品久久久久久久app| 久久se精品一区二区| 久久久久亚洲AV无码观看| 99久久www免费人成精品| 色欲av伊人久久大香线蕉影院| 久久精品国产99久久香蕉| 久久精品成人国产午夜| 色偷偷久久一区二区三区| 无码人妻久久一区二区三区蜜桃| 久久这里只有精品久久| 国产精品女同久久久久电影院| 久久综合五月丁香久久激情| 亚洲一本综合久久| 国产精品久久久久久久久鸭| 婷婷伊人久久大香线蕉AV| 欧美一区二区久久精品| 伊人久久成人成综合网222| 久久婷婷五月综合成人D啪| 国产精品99久久精品爆乳| 91性高湖久久久久| 91精品观看91久久久久久| 人人狠狠综合久久亚洲88| 伊人久久免费视频| 国内精品久久久久久久涩爱| 久久国产香蕉一区精品|