BZOJ 4212:牛の神が持続するための計画を策定することができトライ+トライ

アイデアは難しかったが、多くの場合、ああ〜このタイトルカードされていません 

コード: 

#include <ビット/ STDC ++。H>   
#define N 2000004  
#define M 1000005  
#define SIZE 2000005    
#define setIO(S)freopenは(S ".IN"、 "R"、標準入力) 
名前空間stdを使用。          
ベクター<INT> G [SIZE]。   
int型N、M、ティム、CNT、すべてのもの。 
文字列str [SIZE]、TMP [SIZE]、T1 [SIZE]、T2 [SIZE]。   
int型ST [N]、ED [N]、DFN [N]、CH [SIZE] [26]、BA [SIZE]、サイズ[SIZE]、OU [SIZE]、RT [SIZE]、COUN [SIZE]、トランス[SIZE] [26]。  
インラインINT newnode(){リターン++ CNT。}   
ボイドinsert_trie(int型L、INT R、int型のID)   
{ 
    int型になりました= 0;    
    (; I <= R; ++ iはLを= INT)のために 
    {     
        (もし!CH [今] [STR [I]  -  ''])CH [今] [STR [i]は ' - '] = ++ TOT;   
        今= CH [今] [STR [I]  -  '']。                     
    }          
    G [今] .push_back(ID)。    
}  
無効DFS(int型U) 
{
    DFN [U] = ++ティム、BA [ティム] = U、サイズ[U] = 1。  
    以下のために(; I <26; INT iが0 = ++ I)、IF(CH [U] [i])とDFS(CH [U] [i])とサイズ[U] + =サイズ[CH [U] [I ]。      
    または[U] =ティム。       
}       
空挿入(int型のID、int型の前、INT&POS)      
{   
    INT I、J、R = ED [ID]、L = ST [ID]。     
    int型になりました= POS = newnode();       
    ( -  I; I> = L iはR =)を用 
    {                   
        用(J = 0であり、j <26; ++ j)はトランス[今] [J] =トランス -  [事前] [J]。                
        トランス[今] [STR [I]  -  ''] = newnode()。         
        事前=トランス[事前] [STR [I]  -  [A ']。  
        [今]今=トランス[STR [I]  -  ''];   
        COUN [今] = COUN [事前] +1。                
    }                
}    
メインint型() 
{ 
    // setIO( "入力");  
    私は、jはint型。     
    scanf関数( "%のD"、&N);   
    ための式(I = 1; iが<= N; ++ I)          
    {    
        ED [I] = STRLEN(STR + 1)。              
        ST [I] = STRLEN(STR + 1)+1。   
        scanf関数( "%s" は、TMP + 1)。  
        INT LEN = STRLEN(TMP + 1)。  
        用(J = 1; J <= LEN; ++ j)のSTR [++ ED [I] = TMP [J]。        
    }        
    ための式(I = 1; iが<= N; ++ I)insert_trie(ST [i]は、ED [i]は、I)。             
    DFS(0)。     
    以下のための式(I = 1; I <=ティム; ++ I) 
    {             
        RT [I] = RT [I-1];  
        用(J = 0; J <(INT)G [BA [I]サイズ(); ++ j)の挿入(G [BA [I]、[J]、RT [i]は、RT [i])と;               
    }                  
    scanf関数( "%のD"、&M)。       
    あなたは0 = lastans。   
    しばらく(M--)  
    {   
        scanf関数( "%S%S"、T1 + 1、T 2 + 1)。     
        INT LEN1 = STRLEN(T1 + 1)、LEN2 = STRLEN(T2 + 1)、今= 0。 
        ;%26  -  T1 [J] = '+( '' + lastans T1 [J])(; J <= LEN1 ++ J J = 1)のために   
        ;%26  -  T2 [J] = '+( '' + lastans T2 [J](); J <= LEN2 ++ J J = 1)のために                               
        用(J = 1; J <= LEN1; ++ j)は今= CH [今] [T1 [J]  -  '']。             
        もしlastans = 0、のprintf( "0 \ N")(今!)。 
        {
            INT再= 0、L = RT [DFN [今] -1]、R = RT [OU [今]。                              
            (J = LEN2あり、j> = 1;  -  j)のための 
            {   
                L =トランス -  [L] [T2 [J]  -  '']。                        
                R =トランス[R] [T2 [J]  -  '']。          
            }          
            printf( "%dの\ n" は、lastans = COUN [R] -coun [L])。   
        }
    }
    0を返します。 
}

  

おすすめ

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