前缀统计
这道题就是一个很简单的trie树的题
先把建立索引的字符串存下来
然后在查询即可
#include <bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int n,m;
int son[N][30],cnt[N],idx=1;
char str[N];
void insert()
{
int p=0;
for(int i=0;str[i];i++)
{
int s=str[i]-'a';
if(!son[p][s]) son[p][s]=idx++;
p=son[p][s];
}
cnt[p]++;
}
int query()
{
int p=0,res=0;
for(int i=0;str[i];i++)
{
int s=str[i]-'a';
if(!son[p][s]) break;
p=son[p][s];
res+=cnt[p];
}
return res;
}
int main()
{
cin>>n>>m;
while(n--)
{
scanf("%s",str);
insert();
}
while(m--)
{
scanf("%s",str);
printf("%d\n",query());
}
return 0;
}
The XOR Largest Pair(最大异或对)
这道题是trie树的另一种应用
trie树不仅可以用来存储字符串,还可以用来存数
这道题中要求异或值最大的结果是多少,可以把一个数的二进制表示按照从高位到低位存储在trie树中
查询需要贪心的思想,越高的位不同,异或值越大
因此只需要在trie树上按照上述规则走到叶子节点即可
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int n;
int son[31*N][2],idx=1;
void insert(int x)
{
int p=0;
for(int i=30;i>=0;i--) //从最高位开始存
{
int u=x>>i&1;
if(!son[p][u]) son[p][u]=idx++;
p=son[p][u];
}
}
int query(int x)
{
int p=0,res=0;
for(int i=30;i>=0;i--)
{
int u=x>>i&1;
if(son[p][!u])
{
res=res*2+!u;
p=son[p][!u];
}
else
{
res=res*2+u;
p=son[p][u];
}
}
return res;
}
int main()
{
cin>>n;
int res=-1;
for(int i=0;i<n;i++)
{
int x;
cin>>x;
if(!i) insert(x); //处理边界
else
{
int t=query(x);
//cout<<"****"<<t<<endl;
insert(x);
res=max(res,t^x);
}
}
cout<<res<<endl;
return 0;
}