很好的字符串题啊
建立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;
}