【bzoj1030】[JSOI2007]文本產生器

來源:互聯網
上載者:User

標籤:題解   隨機   檔案   輸入   文章   while   div   位元組   space   

題目描述

JSOI交給隊員ZYX一個任務,編製一個稱之為“文本產生器”的電腦軟體:該軟體的使用者是一些低幼人群,他們現在使用的是GW文本產生器v6版。該軟體可以隨機產生一些文章―――總是產生一篇長度固定且完全隨機的文章—— 也就是說,產生的文章中每個位元組都是完全隨機的。如果一篇文章中至少包含使用者們瞭解的一個單詞,那麼我們說這篇文章是可讀的(我們稱文章a包含單詞b,若且唯若單詞b是文章a的子串)。但是,即使按照這樣的標準,使用者現在使用的GW文本產生器v6版所產生的文章也是幾乎完全不可讀的?。ZYX需要指出GW文本產生器 v6產生的所有文本中可讀文本的數量,以便能夠成功獲得v7更新版。你能協助他嗎?

輸入

輸入檔案的第一行包含兩個正整數,分別是使用者瞭解的單詞總數N (<= 60),GW文本產生器 v6產生的文本固定長度M;以下N行,每一行包含一個使用者瞭解的單詞。這裡所有單詞及文本的長度不會超過100,並且只可能包含英文大寫字母A..Z

輸出

一個整數,表示可能的文章總數。只需要知道結果模10007的值。

範例輸入

2 2
A
B

範例輸出

100

題解

AC自動機+dp

由於直接求可讀目數比較難求,所以我們可以求出總數和不可讀數目,然後作差求解。

設f[i][j]為可讀文章中第i個字元對應位置j的數目。

那麼可以推出f[i][t]=f[i-1][j]。

求出每個j能夠對應的t即可。

注意一下邊界條件。

 1 #include <cstdio> 2 #include <cstring> 3 #include <queue> 4 #define MOD 10007 5 using namespace std; 6 queue<int> q; 7 int nt[6001][26] , fail[6001] , cnt[6001] , tot = 1 , f[101][6001]; 8 char str[61]; 9 int qpow(int x , int y)10 {11     int ans = 1;12     while(y)13     {14         if(y & 1)15             ans = ans * x % MOD;16         x = x * x % MOD;17         y >>= 1;18     }19     return ans;20 }21 void build()22 {23     int u , t , i;24     q.push(1);25     while(!q.empty())26     {27         u = q.front();28         q.pop();29         for(i = 0 ; i < 26 ; i ++ )30         {31             if(nt[u][i])32             {33                 q.push(nt[u][i]);34                 t = fail[u];35                 while(t && !nt[t][i])36                     t = fail[t];37                 fail[nt[u][i]] = nt[t][i];38                 cnt[nt[u][i]] |= cnt[nt[t][i]];39             }40         }41     }42 }43 int main()44 {45     int n , m , i , j , k , t , l , ans = 0;46     scanf("%d%d" , &n , &m);47     for(i = 0 ; i < 26 ; i ++ )48         nt[0][i] = 1;49     while(n -- )50     {51         scanf("%s" , str);52         l = strlen(str);53         t = 1;54         for(i = 0 ; i < l ; i ++ )55         {56             if(!nt[t][str[i] - ‘A‘])57                 nt[t][str[i] - ‘A‘] = ++tot;58             t = nt[t][str[i] - ‘A‘];59         }60         cnt[t] = 1;61     }62     build();63     f[0][1] = 1;64     for(i = 1 ; i <= m ; i ++ )65     {66         for(j = 1 ; j <= tot ; j ++ )67         {68             if(!cnt[j] && f[i - 1][j])69             {70                 for(k = 0 ; k < 26 ; k ++ )71                 {72                     t = j;73                     while(!nt[t][k])74                         t = fail[t];75                     t = nt[t][k];76                     f[i][t] += f[i - 1][j];77                     f[i][t] %= MOD;78                 }79             }80         }81     }82     for(i = 1 ; i <= tot ; i ++ )83         if(!cnt[i])84             ans = (ans + f[m][i]) % MOD;85     printf("%d\n" , (qpow(26 , m) - ans + 2 * MOD) % MOD);86     return 0;87 }

 

【bzoj1030】[JSOI2007]文本產生器

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.