自用板子
```
//字典树板子//(有多少个字符满足已经存储的字符的前缀)
int t[N][100], cnt[N], id;
void insert(string s)
{
int p = 0, len = s.size();
for (int i = 0; i < len; i++)
{
int c = s[i]-'0';
if (!t[p][c]) t[p][c] = ++id;
p = t[p][c];
cnt[p]++;
}
}
void del(string s)
{
int p = 0,len = s.size();
for (int i = 0; i < len; i++)
{
int c = s[i]-'0';
p = t[p][c];
cnt[p]--;
}
}
int find(string s)
{
int p = 0, len = s.size();
for (int i = 0; i < len; i++)
{
int c = s[i] - '0';
if (!t[p][c]) return 0;
p = t[p][c];
}
return cnt[p];
}
int main()
{
int T = read();
while (T--)
{
for (int i = 0; i <= id; i++)
for (int j = 0; j <= 100; j++)
t[i][j] = 0;
for (int i = 0; i <= id; i++)cnt[i] = 0;
id = 0;
int n = read(), q = read();
for (int i = 1; i <= n; i++)
{
string s = sread();
insert(s);
}
for (int i = 1; i <= q; i++)
{
string s = sread();
printf("%d\n", find(s));
}
}
return 0;
}
//01字典树板子//操作:字典树中异或x最大的值;
int t[N * 30][2], cnt[N * 30], id, vis[N * 30];//int范围一般30,LL范围一般60//
void insert(int x)
{
int p = 0;
for (int i = 30; i >= 0; i--)
{
int c = x >> i & 1;
if (!t[p][c]) t[p][c] = ++id;
p = t[p][c];
cnt[p]++; //cnt[p]++放里面存前缀,放外面存字符个数//
}
vis[p] = x;
}
void del(int x)
{
int p = 0;
for (int i = 30; i >= 0; i--)
{
int c = x >> i & 1;
p = t[p][c];
cnt[p]--; //同理删前缀;
}
}
int find(int x)
{
int p = 0;
for (int i = 30; i >= 0; i--)
{
int c = x >> i & 1;
if (t[p][c ^ 1] && cnt[t[p][c ^ 1]])p = t[p][c ^ 1];
else p = t[p][c];
}
return x^vis[p];
}
```