字典树(tire树)

  字典树功能:

给定n个主串平均长度为len1,m个模式串平均长度为len2,问m个模式串分别在n个字符串中出现了几次?

首先如果用kmp算法,对于n个主串每个主串都和m个模式串进行比较,那么对于每一个主串来说相当于进行了m次kmp所以单个主串需要的时间是mlen1,有n个主串则时间复杂度为O(nmlen1)而接下来介绍的字典树的时间复杂度为O(nlen1+mlen2)

字典树:

(1) 时间复杂度假设所有字符串长度之和为n,构建字典树的时间复杂度为O(n)
假设要查找的字符串长度为k,查找的时间复杂度为O(k)

(2) 空间复杂度有公共前缀的单词只需要存一次公共前缀,节省了空间

  • 1、维护字符串集合(即字典)。

  • 2、向字符串集合中插入字符串(即建树)。

  • 3、查询字符串集合中是否有某个字符串(即查询)。

  • 4、统计字符串在集合中出现的个数(即统计)。

  • 5、将字符串集合按字典序排序(即字典序排序)。

  • 6、求集合内两个字符串的LCP(Longest Common Prefix,最长公共前缀)(即求最长公共前缀)。

模板: HDU1251


int cnt=0;
int tree[maxn][30];
int num[maxn];//统计前缀出现次数 
void insert(string s){
	int u=0;
	for(int i=0;i

字典树用来加速查询,即n个模式串中的出现的情况,例如最大最小值等,假设有n个字符串它们的平均长度是K,如果用map存这n个字符串,查询每一个时的用时是log(n),如果用字典树来存这n个字符串,那么查询每一个时的用时是K,当K比log(n)小时就可以加速查询

https://ac.nowcoder.com/acm/contest/11222/F

#include
#define int long long
using namespace std;
const int inf=1e9+7;
const int maxn=4e5+5;
struct node{
	int l,r;
};
node a[maxn];
int cnt[15]; //分别用来表示1-10时候的cnt 
int tree[15][maxn][15];
int val[15][maxn]; //统计长度为1-10时分别的最小答案 
vectorb(15);
void insert(vectorv,int vall,int changdu){
	//cout<<"insert ";
	/*for(int i=1;i<=changdu;i++){
		cout<v,int changdu){
	int now=0;
	for(int i=1;i<=changdu;i++){
		if(!tree[changdu][now][v[i]]){
			return -1;
		}
		now=tree[changdu][now][v[i]];
	}
	return val[changdu][now];
}
signed main(){
	for(int i=1;i<=10;i++){
		for(int j=0;j<=maxn-1;j++){
			val[i][j]=inf;
		}
	}
	for(int i=1;i<=10;i++){
		b[i]=i;
		insert(b,0,i);
	}
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>a[i].l>>a[i].r;
	}
	for(int i=1;i<=10;i++){
		for(int j=1;j<=n;j++){  //枚举右端点   
			for(int k=1;k<=i;k++){
				b[k]=k;
			}
			for(int k=j;k>=1;k--){ //枚举左端点从k到j交换 
				int ll=a[k].l,rr=a[k].r;
				if(rr>i){
					break;
				}
				//cout<<"len"<>changdu;
		for(int i=1;i<=changdu;i++){
			cin>>b[i];
		}
		cout<

字典树求异或最大值

https://codeforces.com/contest/1658/problem/D2

#include
using namespace std;
#define int long long
const int mod=998244353;
const int maxn=6e5+5;
int a[maxn];
int tree[maxn][2];
int cnt=0;
void init(){
	for(int i=0;i<=cnt;i++){
		tree[i][0]=tree[i][1]=0;
	}
	cnt=0;
}
void insert(int x){
	int u=0;
	for(int i=32;i>=0;i--){
		int now=(x>>i)&1ll;
		if(!tree[u][now]){
			tree[u][now]=++cnt;
		}
		u=tree[u][now];
	}
}
int find_max(int x){  //找到所有数里面异或x最大的数
	int u=0;
	int ans=0;
	for(int i=32;i>=0;i--){
		int now=(x>>i)&1ll;
		int want=now^1ll;		
		if(tree[u][want]){
			u=tree[u][want];
			ans+=(1ll<=0;i--){
		int now=(x>>i)&1ll;
		int want=now;	
		if(tree[u][want]){
			u=tree[u][want];
		}
		else{
			ans+=(1ll<>l>>r;
	for(int i=l;i<=r;i++){
		cin>>a[i];
		insert(a[i]);
	}
	for(int i=l;i<=r;i++){
		int x=a[i]^l;
		int minn=find_min(x);
		int maxx=find_max(x);
		if(minn==l&&maxx==r){
			cout<>t;
	while(t--){
		solve();
	}
}

你可能感兴趣的:(c++,开发语言)