Bzoj1030:[JSOI2007]文本生成器

题面

Bzoj

Sol

\(AC\)自动机上\(DP\)
总数\(-\)不合法

# include <bits/stdc++.h>
# define RG register
# define IL inline
# define Fill(a, b) memset(a, b, sizeof(a))
using namespace std;
typedef long long ll;
const int _(6005);
const int Zsy(10007);

IL ll Input(){
    RG ll x = 0, z = 1; RG char c = getchar();
    for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
    for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
    return x * z;
}

int n, m, ans = 1, ch[26][_], fail[_], ed[_], tot, f[500][_];
queue <int> Q;
char s[_];

IL void Insert(){
	RG int l = strlen(s), x = 0;
	for(RG int i = 0; i < l; ++i){
		RG int id = s[i] - 'A';
		if(!ch[id][x]) ch[id][x] = ++tot;
		x = ch[id][x];
	}
	ed[x] = 1;
}

IL void BuildFail(){
	for(RG int i = 0; i < 26; ++i) if(ch[i][0]) Q.push(ch[i][0]);
	while(!Q.empty()){
		RG int u = Q.front(); Q.pop();
		for(RG int i = 0; i < 26; ++i)
			if(!ch[i][u]) ch[i][u] = ch[i][fail[u]];
			else fail[ch[i][u]] = ch[i][fail[u]], Q.push(ch[i][u]);
		ed[u] |= ed[fail[u]];
	}
}

IL void Chk1(RG int &x, RG int y){
	x += y;
	if(x >= Zsy) x -= Zsy;
}

IL void Chk2(RG int &x, RG int y){
	x -= y;
	if(x < 0) x += Zsy;
}

int main(RG int argc, RG char* argv[]){
    n = Input(), m = Input();
	for(RG int i = 1; i <= m; ++i) ans = ans * 26 % Zsy;
	for(RG int i = 1; i <= n; ++i) scanf(" %s", s), Insert();
	BuildFail(), f[0][0] = 1;
	for(RG int i = 0; i < m; ++i)
		for(RG int j = 0; j <= tot; ++j){
			if(!f[i][j] || ed[j]) continue;
			for(RG int k = 0; k < 26; ++k)
				if(!ed[ch[k][j]]) Chk1(f[i + 1][ch[k][j]], f[i][j]);
		}
	for(RG int i = 0; i <= tot; ++i) if(!ed[i]) Chk2(ans, f[m][i]);
	printf("%d\n", ans);
    return 0;
}

posted @ 2018-02-10 14:28  Cyhlnj  阅读(82)  评论(0编辑  收藏