問題の意味
:によって与えられるn個の文字列
が文字列に1つの文字であることを示す文字、続いて、1であれば、i番目の行番号入力操作
番号jが続くが2である場合、
、および形成呪文を、以下のi、j番目の文字列で記述された文字列。
そこは、その後たびに、与えられた文字列と整数のI、Sは、いくつかの中で発生したリクエスト文字列のi番目の文字列をm回を頼まれます
データ範囲
全ての整数以下で4E5、文字列クエリの全長未満4E5
ソリューション
AC自動機に対応する文字列に尋ねられたときに最初のトピックは、実行、クエリの答えに(元の文字列は、ツリー構造の数の形成を観察することができます)ツリーの元の形式でクエリ文字列AC自動機、およびその文字列を構築することです右の理由のために、ここで、いくつかありました実際には、ACオートマトンのこのチェーンの現在の情報を保持したときに、私たちは木DFS元の文字列の形式であるためです。これはオイラーの順序を維持することができる、AC自動機プラスサブツリーの動作であるべきです。
#include<bits/stdc++.h>
using namespace std;
const int maxn=4e5+5;
inline int read(){
char c=getchar();int t=0,f=1;
while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){t=(t<<3)+(t<<1)+(c^48);c=getchar();}
return t*f;
}
int n,m;
typedef pair<int,int> pii;
vector<pii> son[maxn],q[maxn];
char c[maxn],s[5];
int ch[maxn][26],val[maxn],fail[maxn],cnt;
inline int add(){
int now=0,l=strlen(c);
for(int i=0;i<l;i++){
if(!ch[now][c[i]-'a'])ch[now][c[i]-'a']=++cnt;
now=ch[now][c[i]-'a'];
}
return now;
}
vector<int> F[maxn];
void build(){
queue<int> q;
for(int i=0;i<26;i++)if(ch[0][i])q.push(ch[0][i]);
while(!q.empty()){
int u=q.front();q.pop();
for(int i=0;i<26;i++){
if(ch[u][i]){
fail[ch[u][i]]=ch[fail[u]][i];
q.push(ch[u][i]);
}
else{ch[u][i]=ch[fail[u]][i];}
}
}
for(int i=1;i<=cnt;i++)F[fail[i]].push_back(i);
}
int dfn,din[maxn],dout[maxn],ans[maxn];
void dfs(int u){
din[u]=++dfn;
for(int i=0;i<F[u].size();i++){
int v=F[u][i];
dfs(v);
}
dout[u]=dfn;
}
int tr[maxn*5];
inline int lowbit(int x){return x&(-x);}
inline void modify(int x,int val){
while(x<=dfn){tr[x]+=val;x+=lowbit(x);}
}
inline int query(int x){
int ans=0;
while(x){ans+=tr[x];x-=lowbit(x);}
return ans;
}
void dfs2(int u,int now){
modify(din[u],1);
for(int i=0;i<q[now].size();i++){
pii t=q[now][i];
ans[t.second]=query(dout[t.first])-query(din[t.first]-1);
}
for(int i=0;i<son[now].size();i++){
pii t=son[now][i];
dfs2(ch[u][t.first],t.second);
}
modify(din[u],-1);
}
int main(){
n=read();
for(int i=1;i<=n;i++){
int op=read();int fa=0;
if(op==1);
else{fa=read();}
scanf("%s",s);
son[fa].push_back(pii(s[0]-'a',i));
}
m=read();
for(int i=1;i<=m;i++){
int d;
scanf("%d%s",&d,c);
q[d].push_back(pii(add(),i));
}
build();
dfs(0);
dfs2(0,0);
for(int i=1;i<=m;i++){
printf("%d\n",ans[i]);
}
return 0;
}