01 Application of Dictionary Tree

01 Application of Dictionary Tree

01 Trie can quickly process a bunch of numbers.
Since the trie tree is relatively close to the string, we will try our best to convert the number into a string.
That's right! It's binary!

Insert picture description here

01Trie application (1):
Given a set, asking multiple times, each time giving a number, find the maximum value of the exclusive OR of this number and the number in the set.

According to the nature of bit operation, the higher the higher bit, the better. Establish Trie according to the binary system of numbers. For an inquiry, go from top to bottom, greedily choose or go in a larger direction until you reach the leaf.

Implementation:

#include<bits/stdc++.h>
#define Rep(a,b,c) for(register int a=b;a<=c;a++)
#define Mem(d,e) memset(d,e,sizeof(d))
using namespace std;
int bits[25],a[300007],cnt=0,opt=0;
 
inline int in(){
    
    
	int W=1,X=0;
	char Ch=0;
	while(!isdigit(Ch)){
    
    
		if(Ch=='-') W=-1;
		Ch=getchar();
	}
	while(isdigit(Ch))
		X=(X<<3)+(X<<1)+(Ch^'0'),Ch=getchar();
	return X*W;
}
 
inline void out(int M,char *s){
    
    
	if(M<0) putchar('-'),M=-M;
	if(M>9) out(M/10,"");
	putchar(M%10+'0');
	printf(s);
	return;
}
 
inline void getbits(){
    
    
	bits[0]=1;
	Rep(i,1,19)
		bits[i]=bits[i-1]<<1;
	return;
}
 
struct Node{
    
    
	int son[2],id;
};
 
struct Trie{
    
    
	Node s[1<<24];
	inline void build(){
    
    
		Mem(s,0),getbits();
	}
	inline void add(int cur,int dep,int x){
    
    
		if(dep<0) {
    
    
			s[cur].id=x;
			return;
		}
		bool tmp=bits[dep]&x;
		add(s[cur].son[tmp]=++cnt,dep-1,x);
	}
	inline int query(int cur,int dep){
    
    
		if(dep<0) return s[cur].id;
		bool tmp=bits[dep]&opt;
		if(s[cur].son[tmp^1]);
			return query(s[cur].son[tmp^1],dep-1);
		return query(s[cur].son[tmp],dep-1);
	}
}A;
 
 
int main(){
    
    
	int n,q;
	n=in(),q=in();
	A.build();
	Rep(i,1,n)
		a[i]=in();
	sort(a+1,a+n+1);
	n=unique(a+1,a+n+1)-a-1;
	while(n)
		A.add(0,19,a[n--]);
	while(q--){
    
    
		opt=in();
		out(A.query(0,19),"\n");
	}
}

Application 2-Special 01Trie
CF842D

Brief description of the question:
Maintain a sequence of length n, each time x is given, please do the following:
1.XOR all numbers in the sequence with x
2. Query the mex of this sequence (the smallest non-negative integer that has not appeared). The
problem can be equivalent to:
Given a set, multiple queries, each query gives an x, and asks all numbers in the set to be XORed after x mex
creates a 0/1 Trie and walks down from the top. If the left son is full, recurse to the right son, otherwise recursive to the left son, until the leaf is the answer.

#include <cstdio>
#include <algorithm>
using namespace std;

int trie[6000005][2], tot = 1, has[6000005];

void insert(int n)
{
    
    
    int t = 1;
    for(int i = 20; i > 0; i--)
    {
    
    
        has[t]++;
        if(n & (1 << (i - 1)))
        {
    
    
            if(!trie[t][1]) trie[t][1] = ++tot;
            t = trie[t][1];
        } else {
    
    
            if(!trie[t][0]) trie[t][0] = ++tot;
            t = trie[t][0];
        }
    }
    has[t]++;
}

int dlt = 0;

int query()
{
    
    
    int t = 1, res = 0;
    for(int i = 20; i > 0; i--)
    {
    
    
        if(dlt & (1 << (i - 1)))
        {
    
    
            if(!trie[t][1])
            {
    
    
                return res;
            } else if(has[trie[t][1]] < (1 << (i - 1))) {
    
    
                t = trie[t][1];
            }
            else
            {
    
    
                t = trie[t][0];
                res += (1 << (i - 1));
            }
        }
        else
        {
    
    
            if(!trie[t][0])
            {
    
    
                return res;
            }
            else if(has[trie[t][0]] < (1 << (i - 1)))
            {
    
    
                t = trie[t][0];
            }
            else
            {
    
    
                t = trie[t][1];
                res += (1 << (i - 1));
            }
        }
    }
    return res;
}

int n, m, a[300005], t;

int main()
{
    
    
    scanf("%d%d", &n, &m);
    for(int i = 0; i < n; i++)
    {
    
    
        scanf("%d", &a[i]);
    }
    sort(a, a + n);
    n = unique(a, a + n) - a;
    for(int i = 0; i < n; i++)
    {
    
    
        insert(a[i]);
    }
    for(int i = 0; i < m; i++)
    {
    
    
        scanf("%d", &t);
        dlt ^= t;
        printf("%d\n", query());
    }
    return 0;
}

Guess you like

Origin blog.csdn.net/qq_40534166/article/details/97646997