BZOJ1030:[JSOI2007]文本產生器

來源:互聯網
上載者:User

標籤:pen   scanf   clu   pac   sub   更新   insert   nbsp   can   

1030: [JSOI2007]文本產生器Time Limit: 1 Sec  Memory Limit: 162 MB
Submit: 4859  Solved: 2019
[Submit][Status][Discuss]Description

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

Input

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

Output

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

Sample Input2 2
A
BSample Output100思路{  AC自動機裸題。  然而對於我這種一道AC自動機都沒刷過的  只會匹配的辣雞來說還是比較難的。  肯定想到是DP,怎麼設狀態!  我們應當明確求神馬。直接求方案數不行。  那也可以總情況數減去不行的方案數。  我們想,一個目標串列的話最多走到AC自動機末尾的點前一個為止,或者fail鏈的點前一個。  而目標串只走m步!就DP啦~~~~  dp[i][k]表示匹配 i 步 到 k 點的方案數  那轉移方程:dp[i][ch[k][j]]+=dp[i-1][k];  就可以啦~~~~~~~~~~~}  
#include<bits/stdc++.h>#define RG register#define il inline#define N 60010using namespace std;int ch[N][27],f[N],cc,n,k;char s[N*2];bool in[N];void Insert(){  int now=0,len=strlen(s+1);int h=1;  while(h<=len){    int c=s[h]-‘A‘;    if(!ch[now][c])ch[now][c]=++cc;    now=ch[now][c];h++;  }in[now]=true;}il void getfail(){queue<int>que;  while(!que.empty())que.pop();que.push(0);  while(!que.empty()){    RG int u=que.front();    for(RG int i=0;i<26;++i){      if(ch[u][i])que.push(ch[u][i]),f[ch[u][i]]=(u==0?0:ch[f[u]][i]);      else ch[u][i]=(u==0?0:ch[f[u]][i]);    }      in[u]|=in[f[u]];    que.pop();  }return;}#define MOD 10007int qpow(int a,int b){  if(b==1)return a;if(!b)return 1;  int tmp=qpow(a,(b>>1));  tmp=(tmp*tmp)%MOD;if(b&1)tmp=(tmp*a)%MOD;  return tmp;}int dp[101][N];int main(){  freopen("1.in","r",stdin);  freopen("1.out","w",stdout);  scanf("%d%d",&n,&k);  for(int i=1;i<=n;++i)scanf("%s",s+1),Insert();getfail();  dp[0][0]=1;  for(int i=1;i<=k;++i)    for(int j=0;j<=cc;++j)      if(!in[j]){for(int K=0;K<26;++K){  dp[i][ch[j][K]]+=dp[i-1][j];  if(dp[i][ch[j][K]]>=MOD)dp[i][ch[j][K]]-=MOD;}      }int ans=qpow(26,k);  for(int i=0;i<=cc;++i)if(!in[i])ans-=(dp[k][i]%MOD),ans=(ans+MOD)%MOD;  cout<<ans;  return 0;}

  

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.