NC234268. 文本生成器加强版
描述
输入描述
输入文件的第一行包含两个正整数,分别是使用者了解的单词总数N ( ≤ 60),GW文本生成器 v6生成的文本固 定长度M;
以下N行,每一行包含一个使用者了解的单词。这里所有单词及文本的长度不会超过100,并且只可能包含英文大写字母A..Z
输出描述
一个整数,表示可能的文章总数。只需要知道结果模10007的值。
示例1
输入:
2 2 A B
输出:
100
C++(g++ 7.5.0) 解法, 执行用时: 2897ms, 内存消耗: 238312K, 提交时间: 2022-08-05 22:53:50
#include<bits/stdc++.h> using namespace std; #define fastio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0) #define rep(i,a,b) for(int i=a;i<=b;i++) const int N=8005,M=10007; int t[N][26],cnt,isword[N],fail[N]; void insert(string s){ int x=0; for(auto& i:s){ int k=i-'A'; if(!t[x][k])t[x][k]=++cnt; x=t[x][k]; } isword[x]=1; } void build(){ queue<int>q; rep(i,0,25)if(t[0][i])q.push(t[0][i]); while(!q.empty()){ int k=q.front();q.pop(); rep(i,0,25){ int & son=t[k][i]; if(son)q.push(son),fail[son]=t[fail[k]][i]; else son=t[fail[k]][i]; } } } int ok[N]; void generate(){ memset(ok,1,sizeof(ok)); rep(i,1,cnt){ for(int j=i;j;j=fail[j])if(isword[j])ok[i]=0; } } int dp[10010][6060]; int main(){ fastio; int n,m;cin>>n>>m; rep(i,1,n){ string s;cin>>s;insert(s); } build();generate(); dp[0][0]=1; rep(i,0,m)rep(j,0,cnt)rep(k,0,25){ int son=t[j][k]; if(!ok[son])continue; (dp[i+1][son]+=dp[i][j])%=M; } int ans=0,ans2=1; rep(j,0,cnt)(ans+=dp[m][j])%=M; rep(i,1,m)(ans2*=26)%=M; cout<<(ans2-ans+M)%M<<endl; }
C++(clang++ 11.0.1) 解法, 执行用时: 4054ms, 内存消耗: 274816K, 提交时间: 2023-05-13 19:52:33
#include<bits/stdc++.h> using namespace std; const int N=10007; int n,m,t[N][27],cnt,ne[N],tag[N],tot,tt[N],sum=1,f[11111][N],ans; string s; void add(){ int p=0,len=s.size(); for(int i=0;i<len;i++){ int j=s[i]-'A'; if(!t[p][j])t[p][j]=++cnt; p=t[p][j]; } tag[p]=1; } void kmp(){ queue<int>q; for(int i=0;i<26;i++)if(t[0][i])q.push(t[0][i]); while(!q.empty()){ int p=q.front(); q.pop(); tt[++tot]=p; for(int i=0;i<26;i++){ int j=t[p][i],v=t[ne[p]][i]; if(j){ ne[j]=v; q.push(j); tag[j]|=tag[v]; } else t[p][i]=v; } } } int main(){ cin>>n>>m; for(int i=1;i<=n;i++){ cin>>s; add(); } kmp(); f[0][0]=1; for(int i=1;i<=m;i++){ sum=sum*26%N; for(int j=0;j<=tot;j++){ for(int v=0;v<26;v++){ int k=t[tt[j]][v]; if(!tag[k])f[i][k]=(f[i][k]+f[i-1][tt[j]])%N; } } } for(int i=0;i<=cnt;i++)ans=(ans+f[m][i])%N; cout<<(sum+N-ans)%N; }