BZOJ 1030 [JSOI2007] text generator (ac automaton + dp)

The meaning of problems

N number of program strings to you, the request string m in length, so that the string contains at least any one of a string of the n

Thinking

Conversion for the sake number scheme nor the
\ (DP [i] [j] \) is the i-th character, matches the j-th node on the ac automaton number of programs, obviously can not match to have an end point where
fail nature node: node points where the current longest suffix string
so the current node is the end point node fail nor
any empty nodes not originally in the build will point to the root node when
it is empty node in dp [i] [0 ]in

Code

A small open space has been wa

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<deque>
#include<set>
#include<vector>
#include<map>
    
#define fst first
#define sc second
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lc root<<1
#define rc root<<1|1

using namespace std;

typedef double db;
typedef long double ldb;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PI;
typedef pair<ll,ll> PLL;

const db eps = 1e-6;
const int mod = 10007;
const int maxn = 5e5+100;
const int maxm = 2e6+100;
const int inf = 0x3f3f3f3f;
const db pi = acos(-1.0);

int dp[111][7777];
int n,m;
struct AC{
    //局部变量没有默认0!
    int trie[maxn][26];
    int num[maxn];//单词出现次数
    int fail[maxn];
    int vis[maxn];//ask函数用到
    int tot;

    //多测可写个init
    void init(){tot=0;mem(vis,-1);mem(trie,0);}
    void add(char *s){
        int root = 0, len = strlen(s+1);
        for(int i = 1; i <= len; i++){
            int x = s[i]-'A';
            if(!trie[root][x])trie[root][x]=++tot;
            root=trie[root][x];
        }
        num[root]++;
        vis[root]=0;
    }
    void build(){
        queue<int>q;
        for(int i = 0; i < 26; i++){
            if(trie[0][i]){
                fail[trie[0][i]]=0;
                q.push(trie[0][i]);
            }
        }
        while(!q.empty()){
            int now = q.front();
            q.pop();
            for(int i = 0; i < 26; i++){
               if(trie[now][i]){
                    fail[trie[now][i]]=trie[fail[now]][i];
                    q.push(trie[now][i]);
                }
                else trie[now][i]=trie[fail[now]][i];
            }
            vis[now]&=vis[fail[now]];
            //if(vis[fail[now]]==0)vis[now]=0;
        }
    }

    void solve(){
        dp[0][0]=1;
        
        for(int i = 0; i < m; i++){
            for(int j = 0; j <= tot; j++){
                if(vis[j]==0)continue;
                for(int k = 0; k < 26; k++){
                    int to = trie[j][k];
                    if(vis[to]==0)continue;
                    (dp[i+1][to]+=dp[i][j])%=mod;
                }
            }
        }
    }

}ac;

char a[maxn];
int main(){
    ac.init();
    scanf("%d %d", &n, &m);
    for(int i = 1; i <= n; i++){
        scanf("%s",a+1);
        ac.add(a);
    }
    ac.build();
    ac.solve();
    int ans = 1;
    for(int i = 1; i <= m; i++){
        ans=ans*26%mod;
    }/*
    for(int j = 0; j <= ac.tot; j++){
        printf("%d %d\n",j,ac.vis[j]);

    }
    for(int i = 0; i <= ac.tot; i++){
        printf("%d:: \n",i);
        for(int j = 0; j < 26; j++){
            printf("%d %d\n",j,ac.trie[i][j]);
        }
    }*/
    /*for(int i = 1; i <= m; i++){
        for(int j = 0; j <= ac.tot; j++){
            printf("%d %d == %d\n",i,j,dp[i][j]);
        }
    }*/
    for(int i = 0; i <= ac.tot; i++){
        ans=(ans+mod-dp[m][i])%mod;
    }
    printf("%d",ans);
    return 0;
}
/*
10 18
DCSDG
DSSF
SADAV
DSATWYYH
FDHFIS
DFGDFGGD
SASSSS
HHEBB
SFTWRTWW
ZSDFZDS
 */

Guess you like

Origin www.cnblogs.com/wrjlinkkkkkk/p/11542363.html