【AC自動機】bzoj4327: JSOI2012 玄武密碼

來源:互聯網
上載者:User

標籤:queue   \n   有一個   關聯   標記   欄位   return   密碼   else   

題目思路沒話講;主要是做題時候的細節和經驗

Description在美麗的玄武湖畔,雞鳴寺邊,雞籠山前,有一塊富饒而秀美的土地,人們喚作進香河。相傳一日,一縷紫氣從天而至,只一瞬間便消失在了進香河中。老人們說,這是玄武神靈將天書藏匿在此。 很多年後,人們終於在進香河地區發現了帶有玄武密碼的文字。更加神奇的是,這份帶有玄武密碼的文字,與玄武湖南岸台城的結構有微妙的關聯。於是,漫長的破譯工作開始了。 經過分析,我們可以用東南西北四個方向來描述台城城磚的擺放,不妨用一個長度為N的序列來描述,序列中的元素分別是‘E’,‘S’,‘W’,‘N’,代表了東南西北四向,我們稱之為母串。而神秘的玄武密碼是由四象的圖案描述而成的M段文字。這裡的四象,分別是東之青龍,西之白虎,南之朱雀,北之玄武,對東南西北四向相對應。 現在,考古工作者遇到了一個難題。對於每一段文字,其首碼在母串上的最大匹配長度是多少呢? Input第一行有兩個整數,N和M,分別表示母串的長度和文欄位的個數。 第二行是一個長度為N的字串,所有字元都滿足是E,S,W和N中的一個。 之後M行,每行有一個字串,描述了一段帶有玄武密碼的文字。依然滿足,所有字元都滿足是E,S,W和N中的一個。 Output輸出有M行,對應M段文字。 每一行輸出一個數,表示這一段文字的首碼與母串的最大匹配串長度。 Sample Input7 3
SNNSSNS
NNSS
NNN
WSEESample Output4
2
0HINT

對於100%的資料,N<=10^7,M<=10^5,每一段文字的長度<=100。

題目分析

題目的做法很顯然:標記一下哪些節點被匹配過,之後再dfs找被匹配過的最大深度。

這裡記錄一下做題經驗:

  1. 字元集能壓縮的盡量壓縮(和離散化一個道理),trie畢竟還有|S|的常數在這裡。
  2. 查詢跳匹配的時候for (int v=u; v&&!vis[v]; v=nxt[v])的!vis[v]這個最佳化非常重要

以上。

 1 #include<bits/stdc++.h> 2 const int maxNode = 10000035; 3 const int maxn = 10000035; 4  5 char s[maxn],t[103]; 6 int n,m,c[100035],l[100035],cnt; 7 struct ACAutomaton 8 { 9     bool vis[maxNode];10     std::queue<int> q;11     int nxt[maxNode],f[maxNode][5],fa[maxNode],tot;12     13     inline int get(char ch)14     {15         if(ch==‘W‘) return 0;16         if(ch==‘E‘) return 1;17         if(ch==‘S‘) return 2;18         return 3;19     }20     void insert(char *s)21     {22         int u = 1, lens = strlen(s);23         for (int i=0; i<lens; i++)24         {25             int c = get(s[i]);26             if (!f[u][c]) f[u][c] = ++tot, fa[f[u][c]] = u;27             u = f[u][c];28         }29         c[++cnt] = u;30     }31     void build()32     {33         for (int i=0; i<4; i++) f[0][i] = 1;34         q.push(1);35         while (q.size())36         {37             int tt = q.front();38             q.pop();39             for (int i=0; i<4; i++)40                 if (f[tt][i])41                     nxt[f[tt][i]] = f[nxt[tt]][i], q.push(f[tt][i]);42                 else f[tt][i] = f[nxt[tt]][i];43         }44     }45     int query(int s, int t)46     {47         for (; s; s=fa[s], t--)48             if (vis[s]) return t;49         return 0;50     }51     void match(char *s)52     {53         int u = 1, lens = strlen(s);54         for (int i=0; i<lens; i++)55         {56             int c = get(s[i]);57             u = f[u][c];58             for (int v=u; v&&!vis[v]; v=nxt[v]) vis[v] = 1;59         }60     }61 }f;62 63 int main()64 {65     scanf("%d%d%s",&n,&m,s);66     f.tot = 1;67     for (int i=1; i<=m; i++)68     {69         scanf("%s",t);70         f.insert(t);71         l[i] = strlen(t);72     }73     f.build(), f.match(s);74     for (int i=1; i<=m; i++)75         printf("%d\n",f.query(c[i], l[i]));76     return 0;77 }

 

 

END

【AC自動機】bzoj4327: JSOI2012 玄武密碼

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.