字典树

字典树

指针写法

struct tire
{
	int count;
	tire *next[26];
	tire()
	{
		for(int i=0;i<26;i++){
			next[i]=NULL;
		}
		count=0;
	}
}root;

void insert(char word[])
{
	tire *r=&root;
	for(int i=0;word[i];i++){
		if(r->next[word[i]-'a']==NULL) r->next[word[i]-'a']=new tire;
		r=r->next[word[i]-'a'];
		r->count++;
	}
}

int search(char word[])
{
	tire *r = &root;
	for(int i=0;word[i];i++){
		r=r->next[word[i]-'a'];
		if(r==NULL) return 0;
	}
	return r->count;
}

数组写法

int trie[1000010][26];   //数组形式定义字典树,值存储的是下一个字符的位置
int num[1000010]={0};   //附加值,以某一字符串为前缀的单词的数量
int pos = 1;

void Insert(char word[])   //在字典树中插入某个单词
{
    int i;
    int c = 0;
    for(i=0;word[i];i++){
        int n = word[i]-'a';
        if(trie[c][n]==0)     //如果对应字符还没有值
            trie[c][n] = pos++;
        c = trie[c][n];
        num[c]++;
    }
}
int Find(char word[])   //返回以某个字符串为前缀的单词的数量
{
    int i;
    int c = 0;
    for(i=0;word[i];i++){
        int n = word[i]-'a';
        if(trie[c][n]==0)
            return 0;
        c = trie[c][n];
    }
    return num[c];
}

01字典树(区间异或)

int tol; //节点个数 
LL val[32*MAXN]; //点的值 
int ch[32*MAXN][2]; //边的值 
 
void init()
{ //初始化 
    tol=1;
    ch[0][0]=ch[0][1]=0;
}
 
void insert(LL x)
{ //往 01字典树中插入 x 
    int u=0;
    for(int i=32;i>=0;i--)
    {
        int v=(x>>i)&1;
        if(!ch[u][v])
        { //如果节点未被访问过 
            ch[tol][0]=ch[tol][1]=0; //将当前节点的边值初始化 
            val[tol]=0; //节点值为0,表示到此不是一个数 
            ch[u][v]=tol++; //边指向的节点编号 
        }
        u=ch[u][v]; //下一节点 
    }
    val[u]=x; //节点值为 x,即到此是一个数 
}
 
LL query(LL x)
{ //查询所有数中和 x异或结果最大的数 
    int u=0;
    for(int i=32;i>=0;i--)
    {
        int v=(x>>i)&1;
        //利用贪心策略,优先寻找和当前位不同的数 
        if(ch[u][v^1]) u=ch[u][v^1];
        else u=ch[u][v];
    }
    return val[u]; //返回结果 
}
posted @ 2018-11-26 17:26  凌乱风中  阅读(176)  评论(0编辑  收藏  举报