
很好的字符串题啊
建立Trie树
纠缠的时候用并查集并起来
然后查询的时候用并查集所代表的节点查询
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int N=2e5+100;
char S[N];
char B[N];
struct Node{
int vis[10];
int fa,end;
int getfa();
}T[N*51];
int cnt=0;
int root=0;
int NewNode(){
++cnt;
T[cnt].fa=cnt;
return cnt;
}
int Node::getfa(){if(&T[fa]==this)return fa;return fa=T[fa].getfa();}
void Insert(char *S){
int now=root;
int len=strlen(S);
for(int i=0;i<len;++i){
if(!T[now].vis[S[i]-'0']){
T[now].vis[S[i]-'0']=NewNode();
}
now=T[T[now].vis[S[i]-'0']].getfa();
}
T[now].end=1;
}
int Query(char *S){
int now=root;
int len=strlen(S);
for(int i=0;i<len;++i){
if(!T[now].vis[S[i]-'0'])return 0;
now=T[T[now].vis[S[i]-'0']].getfa();
}
return T[now].end;
}
int Aceess(char *S){
int now=root;
int len=strlen(S);
for(int i=0;i<len;++i){
if(!T[now].vis[S[i]-'0']){
T[now].vis[S[i]-'0']=NewNode();
}
now=T[T[now].vis[S[i]-'0']].getfa();
}
return now;
}
void Merge(int x,int y){
if(x==y)return;
T[x].fa=y;
T[y].end|=T[x].end;
for(int i=0;i<10;++i){
int sonx=T[T[x].vis[i]].getfa();
int sony=T[T[y].vis[i]].getfa();
if(sonx){
if(!sony){
T[y].vis[i]=sonx;
}
else{
Merge(sonx,sony);
y=T[y].getfa();
}
}
}
}
int main(){
// freopen("quantum.in","r",stdin);
// freopen("quantum.out","w",stdout);
int T;
scanf("%d",&T);
while(T--){
int opt;
scanf("%d",&opt);
if(opt==1){
scanf("%s",S);
Insert(S);
}
if(opt==2){
scanf("%s",S);
cout<<Query(S)<<'\n';
}
if(opt==3){
scanf("%s%s",S,B);
Merge(Aceess(S),Aceess(B));
}
}
return 0;
}
本文介绍了一种使用Trie树和并查集的数据结构解决复杂字符串匹配问题的方法。通过构建Trie树来高效地插入和查询字符串,并利用并查集进行节点的合并操作,实现字符串的纠缠处理。文章提供了详细的C++代码实现,包括插入、查询和合并节点等功能。

被折叠的 条评论
为什么被折叠?



