又是被水题坑了。。。
一直想不出来看题解说要什么主席树,于是开始打离线算法
结果打到一半发现要强制在线。。No!!!
发现直接AC自动机似乎可做?树剖之后在AC自动机上跑的时候判断一下不就好了吗!连线段树都不要
让后快乐切掉,速度还可以(废话,人家N^2暴力都跑得飞快)
#pragma GCC opitmize("O3")
#pragma G++ opitmize("O3")
#include<queue>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define vs (*s-'a')
#define N 100010
using namespace std;
struct AcAutomation{int son[N*10][26],f[N*10],c[N*10],cnt;queue<int> q; vector<int> p[N*10];inline void clear(){ cnt=1; }inline void insert(char* s,int pos){int x=1,l=0;for(;*s;++s,++l)x=son[x][vs]?son[x][vs]:son[x][vs]=++cnt;c[x]=l; p[x].push_back(pos);}inline void build(){p[1].push_back(N); sort(p[1].begin(),p[1].end());for(int i=0;i<26;++i)if(!son[1][i]) son[1][i]=1;else q.push(son[1][i]),f[son[1][i]]=1;for(int x;!q.empty();q.pop()){x=q.front(); p[x].push_back(N);sort(p[x].begin(),p[x].end());for(int i=0;i<26;++i)if(!son[x][i]) son[x][i]=son[f[x]][i];else q.push(son[x][i]),f[son[x][i]]=son[f[x]][i];}}inline int query(char* s,int l,int r){int ans=0;for(int x=1;*s;++s){x=son[x][vs];for(int j=x;j>1;j=f[j])if(c[j]>ans && *lower_bound(p[j].begin(),p[j].end(),l)<=r){ ans=c[j]; break; }}return ans;}
}AC;
char s[N][12],c[N];
struct edge{ int v,nt; } G[N<<1];
int h[N],d[N],f[N],top[N],son[N],sz[N];
int l[N],r[N],n,m,cnt=0,clk=0,T;
inline void adj(int x,int y){G[++cnt]=(edge){y,h[x]}; h[x]=cnt;G[++cnt]=(edge){x,h[y]}; h[y]=cnt;
}
void dfs(int x,int p){d[x]=d[p]+1; f[x]=p; sz[x]=1;for(int v,i=h[x];i;i=G[i].nt)if(!d[v=G[i].v]){dfs(v,x);sz[x]+=sz[v];if(sz[son[x]]<sz[v]) son[x]=v;}
}
void dgs(int x,int p){l[x]=++clk; top[x]=p; if(son[x]) dgs(son[x],p);for(int v,i=h[x];i;i=G[i].nt)if(!top[v=G[i].v]) dgs(v,v);
}
int gLca(int x,int y,char* s){int ans=0;for(;top[x]!=top[y];y=f[top[y]]){if(d[top[x]]>d[top[y]]) x^=y^=x^=y;ans=max(ans,AC.query(s,l[top[y]],l[y]));}if(d[x]>d[y]) x^=y^=x^=y;return max(ans,AC.query(s,l[x],l[y]));
}
int main(){scanf("%d%d",&n,&T); AC.clear();for(int i=1;i<=n;++i) scanf("%s",s[i]);for(int x,i=2;i<=n;++i) scanf("%d",&x),adj(x,i);dfs(1,0); dgs(1,1);for(int i=1;i<=n;++i) AC.insert(s[i],l[i]);scanf("%d",&m); AC.build();for(int x,y,ans=0;m--;){scanf("%d%d%s",&x,&y,c);x^=ans; y^=ans; ans=gLca(x,y,c);printf("%d\n",ans); ans*=T;}
}