標籤:scan 方案 預先處理 ios 尾碼 任務 tor 表示 start
我現在連AC自動姬都不會,怎麼辦嘛QAQ
原題:
JSOI交給隊員ZYX一個任務,編製一個稱之為“文本產生器”的電腦軟體:該軟體的使用者是一些低幼人群,
他們現在使用的是GW文本產生器v6版。該軟體可以隨機產生一些文章―――總是產生一篇長度固定且完全隨機的文
章—— 也就是說,產生的文章中每個位元組都是完全隨機的。如果一篇文章中至少包含使用者們瞭解的一個單詞,
那麼我們說這篇文章是可讀的(我們稱文章a包含單詞b,若且唯若單詞b是文章a的子串)。但是,即使按照這樣的
標準,使用者現在使用的GW文本產生器v6版所產生的文章也是幾乎完全不可讀的?。ZYX需要指出GW文本產生器 v6
產生的所有文本中可讀文本的數量,以便能夠成功獲得v7更新版。你能協助他嗎?
N <= 60,所有單詞及文本的長度不會超過100
如果一個串的尾碼不能選,這個串當然也不能選
延伸到AC自動姬上就是如果一個串fail指向的節點不能選,這個節點就不能選
然後就可以預先處理出那些節點不能選
然後用f[i][j]表示在文本串走到i時AC自動姬上走到j節點的方案數
首先外層枚舉i,再枚舉j,如果j可選,就枚舉26個字元k,f[i][j]就給j沿著k往下能走到的狀態(包括走fail)v貢獻
能理解這道題怎麼寫,但是似乎不能往更廣泛的地方延伸,想不動東西……感覺狀態不是很好啊QAQ
代碼:
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 using namespace std; 7 const int dalao=10007; 8 int rd(){int z=0,mk=1; char ch=getchar(); 9 while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)mk=-1; ch=getchar();}10 while(ch>=‘0‘&&ch<=‘9‘){z=(z<<3)+(z<<1)+ch-‘0‘; ch=getchar();}11 return z*mk;12 }13 int n,m;14 char s[110]; int ls;15 int nxt[6100][26],fl[6100],tt=0;16 int q[6100],hd=0;17 bool mk[6100];18 int f[110][6100];19 void ist(){20 int tmp=0;21 for(int i=1;i<=ls;++i){22 if(!nxt[tmp][s[i]-‘A‘]) nxt[tmp][s[i]-‘A‘]=++tt;23 tmp=nxt[tmp][s[i]-‘A‘];24 }25 mk[tmp]=true;26 }27 void gtac(){28 for(int i=0;i<26;++i)if(nxt[0][i]) q[++hd]=nxt[0][i];29 for(int k=1;k<=hd;++k)for(int i=0;i<26;++i){30 if(!nxt[q[k]][i]) nxt[q[k]][i]=nxt[fl[q[k]]][i];31 else{32 fl[nxt[q[k]][i]]=nxt[fl[q[k]]][i],q[++hd]=nxt[q[k]][i];33 mk[nxt[q[k]][i]]|=mk[nxt[fl[q[k]]][i]];34 }35 }36 }37 int main(){//freopen("ddd.in","r",stdin);38 cin>>n>>m;39 for(int i=1;i<=n;++i) scanf("%s",s+1),ls=strlen(s+1),ist();40 gtac();41 f[0][0]=1;42 for(int i=1;i<=m;++i)for(int j=0;j<=tt;++j)if(!mk[j] && f[i-1][j])43 for(int k=0;k<26;++k)44 f[i][nxt[j][k]]=(f[i][nxt[j][k]]+f[i-1][j])%dalao;45 int bwl=0,ans=1;46 for(int i=1;i<=m;++i) ans=(ans*26)%dalao;47 for(int i=0;i<=tt;++i)if(!mk[i]) bwl=(bwl+f[m][i])%dalao;48 cout<<(ans-bwl+dalao)%dalao<<endl;49 return 0;50 }View Code
【BZOJ1030】【JSOI2007】文本產生器