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; }