题目一 Tire字符串
解题思路
index相当于一个分配器,只有需要插入新结点时才会增加
代码模板
#include<iostream>
using namespace std;
const int N=1e5+10;
int son[N][26],count[N],index;
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]=++index;
p=son[p][u];
}
count[p]++;
}
int quary(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 count[p];
}
int main()
{
int n;
cin>>n;
while(n--)
{
char t,str[N];
cin>>t;
if(t=='I')
{
cin>>str;
insert(str);
}
else if(t=='Q')
{
cin>>str;
cout<<quary(str)<<endl;
}
}
return 0;
}
题目二 最大异或对
解题思路
ps:不是放在这章里真的一点想不到这个方法
总体思路为将待求数二进制形式存储在Tire树中,通过树型数据结构快速求取某数的最佳匹配值,最后求与运算。重在理解tire树的物理结构和逻辑结构。
为什么son取M=N*31https://www.acwing.com/solution/content/143064/
代码模板
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1e5+10,M=31*N;
int a[N],son[M][2],index;
void insert(int x)//插入tire树
{
int p=0;
for(int i=30;i>=0;i--)
{
int u=x>>i&1;
if(!son[p][u])son[p][u]=++index;
p=son[p][u];
}
}
int quary(int x)//求最优匹配数
{
int p=0,res=0;
for(int i=30;i>=0;i--)
{
int u=x>>i&1;
int k=u;
if(son[p][!u])k=!k;
p=son[p][k];
res=res*2+k;
}
return res;
}
int main()
{
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)scanf("%d",&a[i]);
int res=0;
for(int i=0;i<n;i++)
{
insert(a[i]);
int t=quary(a[i]);
res=max(res,a[i]^t);
}
cout<<res<<endl;
return 0;
}