关于字典树
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自动机的感觉 就先扔下了