和Leo一起做爱字符串的好孩子量子纠缠

版权声明:LeoJAM Presents https://blog.csdn.net/fcb_x/article/details/82666576

很好的字符串题啊

建立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;
}

猜你喜欢

转载自blog.csdn.net/fcb_x/article/details/82666576