BZOJ 3530:[Sdoi2014] AC回数オートマトン+ DP

アイデアは、特に注意を払うように、多くの詳細と依然として困難ではありませんが、。 

コード: 

書式#include <cstdioを>  
書式#include <キュー> 
書式#include <CStringの>   
書式#include <アルゴリズム>  
#define N 2005 
#define LL長い長いです  
#defineモッズ十億七    
#define setIO(S)freopenは(S ".IN"、 "R"、標準入力) 
名前空間stdを使用。
キュー<整数> Q;  
文字列str [N]、S [N]。           
整数N、M、TOT、CH [N] [10] F [N]、DP [N] [N] [2]、タグ[N]。  
空のインサート() 
{
    INT I、J、LEN = STRLEN(STR + 1)、P = 0。 
    以下のための式(I = 1; I <= LEN; ++ I) 
    {     
        もし -  CH [P] [STR [I]  -  '0'] = ++ TOT(CH [P] [STR [i]が '0']!)。                
        P = CH [P] [STR [I]  -  '0']。        
    }   
    タグ[P] = 1。 
}         
空のビルド() 
{  
    私は、jはint型。                          
    (CH [0] [i])とq.push(CH [0] [i])とIF(++ I; I <10、I = 0)ため、   
    しばらく(!q.empty()) 
    {
        INT U = q.front(); q.pop()。      
        タグ[U] | =タグ[F [U]。  
        以下のための式(I = 0、I <10; ++ I) 
        {
            INT QR = CH [U] [I]。 
            もし{CH [U] [I] = CH [F [U] [I](QR!)。継続する; }   
            F [QR] = CH [F [U] [i]は、     
            q.push(QR)。   
        }
    }
}
メインint型() 
{ 
    // setIO( "入力"); 
    私は、jはint型。              
    scanf関数( "%sの%D"、S + 1、&M)。  
    N = STRLEN(S + 1)。 
    ため(I 1 =、iが<= M; ++ I)のscanf( "%s" は、STR + 1)、挿入()。 
    ビルド();             
    ための式(I = 1; iが<S [1]  -  '0'; ++ i)が(!タグ[CH [0] [I])DP [1] [CH [0] [I] [0の場合] + = 1;        
    IF(!タグ[CH [0] [S [1]  -  '0']])DP [1] [CH [0] [S [1]  -  '0']] [1] = 1。   
    以下のための式(I = 1、I <N; ++ I) 
    {   
        用(J = 1、J <10; ++ j)は(!タグ[CH [0] [J])であれば、DP [I + 1] [CH [0] [j] [0] + = 1;        
        用(J = 0であり、j <= TOT; ++ j)は 
        {         
            (タグ[J])続行。    
            もし(DP [I] [J] [0])  
            {   
                用(int型のk = 0; K <10; ++ K)              
                {
                    IF(タグ[CH [J] [K])続けます。   
                    (DP [I + 1] [CH [J] [K] [0] + = DP [I] [J] [0])%= MOD。 
                }
            }           
            IF(DP [I] [J] [1]) 
            {          
                用(int型のk = 0; K <S [I + 1]  -  '0'; ++ K)    
                {
                    IF(タグ[CH [J] [K])続けます。    
                    (DP [I + 1] [CH [J] [K] [0] + = DP [I] [J] [1])。   
                }
            }  
            IF(タグ[CH [J] [S [I + 1]  -  '0']])続けます。    
            DP [I + 1]、[CH [J] [S [I + 1]  -  '0']] [1] | = DP [I] [J] [1];        
        }
    } 
    INT年= 0; 
    以下のための式(I = 0; I <= TOT; ++ I) 
    {
        (タグ[I])を続ける場合。    
        (ANS + = DP [n]は[I] [0])%= MOD。 
        (ANS + = DP [n]は[I] [1])%= MOD。     
    }
    printf( "%dの\ n" は、ANS)。 
    0を返します。 
}

  

おすすめ

転載: www.cnblogs.com/guangheli/p/12088256.html