// // // // // // // // // // // // // //

关于字典树

Trie 字典树

1. Phone List

/*
  Time: 1.9
  Worker: Blank_space
  Source: #10049. 「一本通 2.3 例 1」Phone List
*/
/*---------------------------------------------------*/
#include<cstdio>
#include<cstring>
#define emm(x) memset(x, 0, sizeof x)
using namespace std;
/*---------------------------------------------------*/
const int A = 1e4 + 7;
const int B = 1e5 + 7;
const int C = 1e6 + 7;
const int D = 1e7 + 7;
const int mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
/*---------------------------------------------------*/
int T, _t, t[B][12], end[B], p, tot;
bool flag, _flag;
char s[12];
/*---------------------------------------------------*/
int read()
{
	int x = 0, f = 1; char ch = getchar();
	while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = getchar();}
	while(ch >= '0' && ch <= '9') {x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar();}
	return x * f;
}
void scan() {emm(t); emm(end); _t = read(); flag = 0; tot = 1;}
bool insert(char c[])
{
	int len = strlen(c + 1);
	for(int i = 1; i <= len; i++)
	{
		int k = c[i] - 48;
		if(!t[p][k]) t[p][k] = ++tot;
		else if(i == len) _flag = 1;
		p = t[p][k];
		if(end[p]) _flag = 1;
	}
	end[p] = 1;
	return _flag;
}
void work()
{
	scan();
	while(_t--)
	{
		scanf("%s", s + 1); _flag = 0; p = 1; 
		if(!flag) flag = insert(s);
	}
	if(flag) puts("NO");
	else puts("YES");
}
/*---------------------------------------------------*/
int main()
{
//	freopen("", "r", stdin);
//	freopen("", "w", stdout);
	
	T = read();
	while(T--) work();
	
//	fclose(stdin);
//	fclose(stdout);
}

2. The XOR Largest Pair

/*
  Time: 1.9
  Worker: Blank_space
  Source: #10050. 「一本通 2.3 例 2」The XOR Largest Pair
  01二叉树 对于每一个输入的数 先建立字典树 然后查找检查每一位 取反 在树中判断 同时进行处理 
*/
/*---------------------------------------------------*/
#include<cstdio>
#include<algorithm>
using namespace std;
/*---------------------------------------------------*/
const int A = 1e4 + 7;
const int B = 1e5 + 7;
const int C = 1e6 + 7;
const int D = 1e7 + 7;
const int mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
/*---------------------------------------------------*/
int n, t[D][3], tot = 1, p, now, ans;
/*---------------------------------------------------*/
int read()
{
	int x = 0, f = 1; char ch = getchar();
	while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = getchar();}
	while(ch >= '0' && ch <= '9') {x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar();}
	return x * f;
}
void insert(int x)
{
	p = 1;
	for(int i = (1 << 30); i; i >>= 1)
	{
		int c = (x & i) ? 1 : 0;
		if(!t[p][c]) t[p][c] = ++tot;
		p = t[p][c];
	}
}
void find(int x)
{
	p = 1;
	for(int i = (1 << 30); i; i >>= 1)
	{
		int c = (x & i) ? 1 : 0;
		if(t[p][c ^ 1]) now |= i, p = t[p][c ^ 1];
		else p = t[p][c];
	}
}
/*---------------------------------------------------*/
int main()
{
//	freopen("", "r", stdin);
//	freopen("", "w", stdout);
	
	n = read();
	for(int i = 1; i <= n; i++)
	{
		int x = read(); now = 0; 
		if(i > 1) find(x);
		insert(x);
		ans = max(ans, now);
	}
	printf("%d", ans);
	
//	fclose(stdin);
//	fclose(stdout);
}

3. Nikitosh 和异或

/*
  Time: 1.9
  Worker: Blank_space
  Source: #10051. 「一本通 2.3 例 3」Nikitosh 和异或
  找两个区间的最大异或值 
*/
/*---------------------------------------------------*/
#include<cstdio>
#include<cstring>
#define emm(x) memset(x, 0, sizeof x)
using namespace std;
/*---------------------------------------------------*/
const int A = 1e4 + 7;
const int B = 1e5 + 7;
const int C = 1e6 + 7;
const int D = 1e7 + 7;
const int mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
/*---------------------------------------------------*/
int n, a[B << 2], l[B << 2], r[B << 2], t[D][2], tot = 1, p, now, ans;
/*---------------------------------------------------*/
int read()
{
	int x = 0, f = 1; char ch = getchar();
	while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = getchar();}
	while(ch >= '0' && ch <= '9') {x = (x << 3) + (x << 1) + (ch ^ 48); ch = getchar();}
	return x * f;
}
int max(int x, int y) {return x > y ? x : y;}
void insert(int x)
{
	int p = 1;
	for(int i = (1 << 30); i; i >>= 1)
	{
		int c = (x & i) ? 1 : 0;
		if(!t[p][c]) t[p][c] = ++tot;
		p = t[p][c];
	}
}
void find(int x)
{
	int p = 1; 
	for(int i = (1 << 30); i; i >>= 1)
	{
		int c = (x & i) ? 1 : 0;
		if(t[p][c ^ 1]) now |= i, p = t[p][c ^ 1];
		else p = t[p][c];
	}
}
/*---------------------------------------------------*/
int main()
{
//	freopen("", "r", stdin);
//	freopen("", "w", stdout);
	
	n = read(); int k = 0; insert(k);
	for(int i = 1; i <= n; i++)
	{
		a[i] = read();
		k ^= a[i]; now = 0;
		insert(k); find(k);
		l[i] = max(l[i - 1], now);
	}
	tot = 1; emm(t); k = 0; insert(k);
	for(int i = n; i >= 1; i--)
	{
		k ^= a[i]; now = 0;
		insert(k); find(k);
		r[i] = max(r[i + 1], now);
		ans = max(ans, l[i] + r[i]);
	}
	printf("%d", ans);
	
//	fclose(stdin);
//	fclose(stdout);
}

4. Immediate Decodability

这个题目好像是没过...


后面的题目有一点AC自动机的感觉 就先扔下了

posted @ 2021-01-30 14:11  Blank_space  阅读(45)  评论(0编辑  收藏  举报
// // // // // // //