BZOJ 4212: 神牛的养成计划 可持久化trie+trie

思路倒是不难,但是这题卡常啊 ~ 

code: 

#include <bits/stdc++.h>   
#define N 2000004  
#define M 1000005  
#define SIZE 2000005    
#define setIO(s) freopen(s".in","r",stdin) 
using namespace std;          
vector<int>G[SIZE];   
int n,m,tim,cnt,tot; 
char str[SIZE],tmp[SIZE],t1[SIZE],t2[SIZE];   
int st[N],ed[N],dfn[N],ch[SIZE][26],ba[SIZE],size[SIZE],ou[SIZE],rt[SIZE],coun[SIZE],trans[SIZE][26];  
inline int newnode() { return ++cnt; }   
void insert_trie(int l,int r,int id)   
{ 
    int now=0;    
    for(int i=l;i<=r;++i) 
    {     
        if(!ch[now][str[i]-'a'])    ch[now][str[i]-'a']=++tot;   
        now=ch[now][str[i]-'a'];                     
    }          
    G[now].push_back(id);    
}  
void dfs(int u) 
{
    dfn[u]=++tim, ba[tim]=u, size[u]=1;  
    for(int i=0;i<26;++i)    if(ch[u][i])    dfs(ch[u][i]),size[u]+=size[ch[u][i]];      
    ou[u]=tim;       
}       
void Insert(int id,int pre,int &pos)      
{   
    int i,j,r=ed[id],l=st[id];     
    int now=pos=newnode();       
    for(i=r;i>=l;--i) 
    {                   
        for(j=0;j<26;++j)    trans[now][j]=trans[pre][j];                
        trans[now][str[i]-'a']=newnode();         
        pre=trans[pre][str[i]-'a'];  
        now=trans[now][str[i]-'a'];   
        coun[now]=coun[pre]+1;                
    }                
}    
int main() 
{ 
    // setIO("input");  
    int i,j;     
    scanf("%d",&n);   
    for(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);  
        for(j=1;j<=len;++j)     str[++ed[i]]=tmp[j];        
    }        
    for(i=1;i<=n;++i)           insert_trie(st[i],ed[i],i);             
    dfs(0);     
    for(i=1;i<=tim;++i) 
    {             
        rt[i]=rt[i-1];  
        for(j=0;j<(int)G[ba[i]].size();++j)    Insert(G[ba[i]][j],rt[i],rt[i]);               
    }                  
    scanf("%d",&m);       
    int lastans=0;   
    while(m--)  
    {   
        scanf("%s%s",t1+1,t2+1);     
        int len1=strlen(t1+1),len2=strlen(t2+1),now=0; 
        for(j=1;j<=len1;++j)    t1[j]='a'+(t1[j]-'a'+lastans)%26;   
        for(j=1;j<=len2;++j)    t2[j]='a'+(t2[j]-'a'+lastans)%26;                               
        for(j=1;j<=len1;++j)    now=ch[now][t1[j]-'a'];             
        if(!now)   lastans=0,printf("0\n"); 
        else 
        {
            int re=0,l=rt[dfn[now]-1],r=rt[ou[now]];                              
            for(j=len2;j>=1;--j) 
            {   
                l=trans[l][t2[j]-'a'];                        
                r=trans[r][t2[j]-'a'];          
            }          
            printf("%d\n",lastans=coun[r]-coun[l]);   
        }
    }
    return 0; 
}

  

posted @ 2019-11-26 19:09  EM-LGH  阅读(140)  评论(0编辑  收藏  举报