牛客题单——trie树、kmp、hash

题单链接

前缀统计

这道题就是一个很简单的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;
}

猜你喜欢

转载自blog.csdn.net/qq_46126537/article/details/114117803
今日推荐