可持久化tire简单题代码求调,码风正常,悬赏关注
查看原帖
可持久化tire简单题代码求调,码风正常,悬赏关注
287411
_脑波_楼主2023/7/20 10:21
#include<bits/stdc++.h>
const int N=1e6+5;
using namespace std;
int n,q,u,v;
string w;
int head[N],esum;
int cnt,tr[N][26],f[N][30],rt[N],siz[N],deep[N];
int en[N];
struct node{
	int to,next;
	string val;
}e[N<<1];
void swap(int &x,int &y){int c=x;x=y;y=c;}
void add(int uu,int vv,string ww){
	e[++esum].to=vv;
	e[esum].val=ww;
	e[esum].next=head[uu];
	head[uu]=esum;
}
int pre(int bh){//子树和预处理 
	int sum=0;
	if(en[bh])sum=-~sum;
	for(int i=0;i<26;i=-~i)if(tr[bh][i]!=0)sum+=pre(tr[bh][i]);
	siz[bh]=sum;
	return sum;
}
void insert(int p,int q,int i,int len,int bb){//插入trie树 
	if(i==len){en[q]=1;return ;}
	if(p!=0)for(int i=0;i<26;i=-~i)tr[q][i]=tr[p][i];
	cnt=-~cnt,tr[q][e[bb].val[i]-'a']=cnt;
	insert(tr[p][e[bb].val[i]-'a'],cnt,i+1,len,bb);
}
int query(int p,string s){//查询trie树 
	for(int i=0;i<s.length();i=-~i){
		p=tr[p][s[i]-'a'];
		if(p==0)return 0;
	}
	return siz[p];//返回子树和 
}
void dfs(int bh,int father){//LCA预处理顺便插点 
	deep[bh]=deep[father]+1,f[bh][0]=father;
	for(int i=1;i<=25;i=-~i)f[bh][i]=f[f[bh][i-1]][i-1];
	for(int i=head[bh];i;i=e[i].next)if(e[i].to!=father)rt[e[i].to]=++cnt,insert(rt[bh],rt[e[i].to],0,e[i].val.length(),i),dfs(e[i].to,bh);
}
int lca(int x,int y){//LCA 
	if(deep[x]<deep[y])swap(x,y);
	for(int i=25;i>=0;i--)if(deep[f[x][i]]>=deep[y])x=f[x][i];
	if(x==y)return x;
	for(int i=25;i>=0;i--)if(f[x][i]!=f[y][i])x=f[x][i],y=f[y][i];
	return f[x][0];
}
int main(){
	std::cin>>n;
	for(int i=1;i<n;i=-~i){
		std::cin>>u>>v>>w;
		add(u,v,w),add(v,u,w);
	}
	dfs(1,-1);
	pre(1);
	std::cin>>q;
	while(q--){
		std::cin>>u>>v>>w;
		std::cout<<query(rt[u],w)+query(rt[v],w)-(query(rt[lca(u,v)],w)<<1)<<std::endl;//u到根路径+v到根路径-2*uv的LCA到根的路径 
	}
}
2023/7/20 10:21
加载中...