字符串统计
树状存储
从根节点向下一串是一个单词,红星是标记,是单词尾的标记
将二十六个字母映射为0~25的数字
#include<iostream>
#include<algorithm>
#include<cstring>
#include<stack>
#include<unordered_map>
using namespace std;
const int N = 100010;
int son[N][26], idx, cnt[N];
void insert(char str[])
{
int p = 0;
for (int i = 0; str[i]; i++)
{
int u = str[i] - 'a';
if (!son[p][u]) son[p][u] = ++idx;
p = son[p][u];
}
cnt[p]++;
}
int qurey(char str[])
{
int p = 0;
for (int i = 0; str[i]; i++)
{
int u = str[i] - 'a';
if (!son[p][u]) return 0;
p = son[p][u];
}
return cnt[p];
}
int main()
{
int n;
cin >> n;
char op[2], str[N];
while (n--)
{
cin >> op >> str;
if (op[0] == 'I')
insert(str);
else if (op[0] == 'Q')
cout << qurey(str)<<endl;
}
return 0;
}
最大异或对
异或举例(异或也可称为不进位加法)
二进制比较,一样则为0,不一样就是1,没有的位数视为0来比较
左移运算
右移运算
#include<iostream>
#include<algorithm>
#include<cstring>
#include<stack>
#include<unordered_map>
using namespace std;
const int N = 100010, M = 3000000;
int son[M][2], idx, a[N];
int n;
void insert(int x)
{
int p = 0;
for (int i = 30; i >= 0; i--)
{
int& s = son[p][x >> i & 1];
if (!s) s = ++idx; //创建新节点
p = s;
}
}
int qurey(int x)
{
int res = 0, p = 0;
for (int i = 30; i >= 0; i--)
{
int s = x >> i & 1;
if (son[p][!s])
{
res += 1 << i;
p = son[p][!s];
}
else p = son[p][s];
}
return res;
}
int main()
{
int n, x;
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> a[i];
insert(a[i]);
}
int res = 0;
for (int i = 0; i < n; i++)
{
res = max(res, qurey(a[i]));
}
cout << res;
return 0;
}