標籤:題解 隨機 檔案 輸入 文章 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]文本產生器