• bzoj 1030


    dp[i][j] 表示,在AC自动机中,从根节点开始,走了i条边,并且经过的点不包含危险节点,走到了j节点的路径数。

    收获:

      1、正难则反

      2、一个字符串不包含给定pattern中的任何一个,则该字符串在AC自动机上走时不会走到“危险节点”。

      3、DFS可以做的事情,可以考虑DP来做。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <vector>
     4 #include <queue>
     5 #define fprintf(...)
     6 #define M 10007
     7 #define maxn 6010
     8 using namespace std;
     9 
    10 int n, len;
    11 int son[maxn][26], fail[maxn], ikey[maxn], ntot;
    12 int dp[102][maxn];
    13 
    14 void insert( const char *P ) {
    15     int n=strlen(P);
    16     int u=0;
    17     for( int i=0; i<n; i++ ) {
    18         int c=P[i]-'A';
    19         if( !son[u][c] ) son[u][c]=++ntot;
    20         fprintf( stderr, "%d->%d %c
    ", u, son[u][c], c+'a' );
    21         u=son[u][c];
    22     }
    23     ikey[u] = true;
    24 }
    25 void build() {
    26     queue<int> qu;
    27     for( int c=0; c<26; c++ ) {
    28         int v=son[0][c];
    29         if( !v ) continue;
    30         qu.push( v );
    31         fail[v] = 0;
    32         fprintf( stderr, "fail[%d] = %d
    ", v, fail[v] );
    33     }
    34     while( !qu.empty() ) {
    35         int u=qu.front();
    36         qu.pop();
    37         for( int c=0; c<26; c++ ) {
    38             int v=son[u][c];
    39             int w=fail[u];
    40             if( !v ) {
    41                 son[u][c] = son[fail[u]][c];
    42                 fprintf( stderr, "%d->%d %c
    ", u, son[u][c], c+'a' );
    43             } else {
    44                 while( w && !son[w][c] ) w=fail[w];
    45                 fail[v] = son[w][c];
    46                 fprintf( stderr, "fail[%d] = %d
    ", v, fail[v] );
    47                 ikey[v] |= ikey[fail[v]];
    48                 qu.push( v );
    49             }
    50         }
    51     }
    52 }
    53 void work() {
    54     dp[0][0] = 1;
    55     for( int i=0; i<=len; i++ ) 
    56         for( int u=0; u<=ntot; u++ )
    57             if( dp[i][u] ) {
    58                 fprintf( stderr, "dp[%d][%d] = %d
    ", i, u, dp[i][u] );
    59                 for( int c=0; c<26; c++ ) {
    60                     int v=son[u][c];
    61                     if( ikey[v] ) continue;
    62                     dp[i+1][v] += dp[i][u];
    63                     if( dp[i+1][v]>=M ) dp[i+1][v]-=M;
    64                 }
    65             }
    66     int ans = 1;
    67     for( int i=1; i<=len; i++ )
    68         ans = (ans*26)%M;
    69     for( int u=0; u<=ntot; u++ ) {
    70         ans -= dp[len][u];
    71         if( ans<0 ) ans+=M;
    72     }
    73     printf( "%d
    ", ans );
    74 }
    75 int main() {
    76     scanf( "%d%d", &n, &len );
    77     for( int i=1; i<=n; i++ ) {
    78         char str[110];
    79         scanf( "%s", str );
    80         insert( str );
    81     }
    82     build();
    83     work();
    84 }
    View Code
  • 相关阅读:
    yii2.0安装redis
    composer
    Windows下安装redis
    Windows下启动redis闪退
    svn的使用及安装
    mysql主从
    linux下远程链接mysql报错1045
    git命令行克隆报错fatal: Could not read from remote repository. Please make sure you have the correct access rights and the repository exists.
    git克隆报错128
    yii phpexcel <转>
  • 原文地址:https://www.cnblogs.com/idy002/p/4339806.html
Copyright © 2020-2023  润新知