Trie树

\(Trie\)

今天搞了不少的好东西,正好趁热整理一下。

\(Trie\)树:

\(Trie\)树,其实就是一种专门用来存储字符串的树型结构。

其基本代码与链式前向星相似。

能够将建树和查询的复杂度降低到一个非常友善的地步:

void add (char c[]){
	int len=strlen(c+1);
	int t=0;
	for(int i=1;i<=len;i++){
		if(!f[t][c[i]-'a']) f[t][c[i]-'a']=++cnt;
		t=f[t][c[i]-'a'];
	}
	cd[t]=1;
}

建树操作。

看吧~与链式前向星特别相似\(qwq\)

以及…… 

\(Trie\)树的模板题:

P2580于是他错误的点名开始了

\(AC\)代码

#include<bits/stdc++.h>
using namespace std;

int n,m,cnt;
char name[50001],report[500001],vis[500001];
int f[500001][30];
int cd[500001];

void add (char c[]){
	int len=strlen(c+1);
	int t=0;
	for(int i=1;i<=len;i++){
		if(!f[t][c[i]-'a']) f[t][c[i]-'a']=++cnt;
		t=f[t][c[i]-'a'];
	}
	cd[t]=1;
}

void check(char c[]){
	int len=strlen(c+1);
	int t=0;
	for(int i=1;i<=len;i++){
		t=f[t][c[i]-'a'];
		if(!t){
			printf("WRONG\n");
			return;
		}
		
	}
	if(!vis[t]&&cd[t]){ printf("OK\n");vis[t]=1;return;}
	if(!cd[t]) {printf("WRONG\n");return ;}
	if(vis[t]) {printf("REPEAT\n");return;}
		
}

int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++){
		scanf("%s",name+1);
		add(name);
	}
	scanf("%d",&m);
	for(int i=1;i<=m;i++){
		scanf("%s",report+1);
		check(report);
	}
	return 0;
}

详细题解

另外:洛谷的测试数据特别特别的水。

举个栗子:

对于一个学生:\(asdfo\)

如果老师念了\(asd\)

那么显然我们应该输出\(WRONG\)

但是!!!

我们输出\(REPEAT\)也能$AC

当然我的代码没有这个问题。

posted @ 2020-09-29 16:58  Luo_Feng_Han  阅读(103)  评论(0编辑  收藏  举报