Hash&map

关于Hash:我不会

所以我们需要map

一、字符串Hash

就是一个公式

大概长这样

Hash(s)=(i=1∑len(s)​s[i]⋅blen−i)modm

看上去是不是很抽象?

因为我不会美观地写公式(技术硬伤)

所以引入大佬的博客

 

不用多说,上代码

#include<bits/stdc++.h>
using namespace std;
namespace _mzf
{
    #define ull unsigned long long
    ull n,ans=1;
    ull base=131;
    const ull N=1e4+100;
    char s[N];
    ull a[N];
    int prime=233317;
    ull mod=21237044013013795711;
    ull hash(char s[])
    {
        int len=strlen(s);
        ull ans=0;
        for(int i=0;i<len;i++)
        ans=(ans*base+(ull)s[i])%mod;//+prime
        return ans;
    }
    void mzfmain()
    {
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            scanf("%s",s);
            a[i]=hash(s);
        }
        sort(a+1,a+1+n);
        for(int i=1;i<n;i++)
        if(a[i]!=a[i+1]) ans++;
        cout<<ans<<endl;
    }
}
int main()
{
    _mzf::mzfmain();
    return 0;
}

二、裸题

可以一边扫一边哈希

轻松水过

#include<bits/stdc++.h>
using namespace std;
namespace _mzf
{
    #define ull unsigned long long
    ull n,ans=1;
    ull base=131;
    const ull N=1e4+100;
    char s[N];
    ull a[N];
    int prime=233317;
    ull mod=21237044013013795711;
    ull hash(char s[])
    {
        int len=strlen(s);
        ull ans=0;
        for(int i=0;i<len;i++)
        ans=(ans*base+(ull)s[i])%mod;//+prime
        return ans;
    }
    void mzfmain()
    {
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            scanf("%s",s);
            a[i]=hash(s);
        }
        sort(a+1,a+1+n);
        for(int i=1;i<n;i++)
        if(a[i]!=a[i+1]) ans++;
        cout<<ans<<endl;
    }
}
int main()
{
    _mzf::mzfmain();
    return 0;
}

关于子串Hash,我从来就没写对过,所以跳过

接下来让我们领略map的魅力

二、map

底层是一个红黑树(又是本蒟蒻不会的算法QAQ)

可以当成一个下表可以是各种乱七八糟东西的数组

常用于离散化和字符串(骗分或减少码量)

我爱map

话不多说直接开骗

一、刚才的一道大水题

#include<bits/stdc++.h>
using namespace std;
namespace _mzf
{
    int n,ans;
    map<string,int> a;
    string s;
    void mzfmain()
    {
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            cin>>s;
            if(!a[s]) ans++,a[s]=1;
            else continue;
        }
        cout<<ans<<endl;
    }
}
int main()
{
    _mzf::mzfmain();
    return 0;
}

轻松骗得满分,mapyyds

二、阅读理解

#include<bits/stdc++.h>
using namespace std;
namespace _mzf
{
    map< string,map<int,int> > a;
    int n,m;
    string s;
    void mzfmain()
    {
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            int x;
            cin>>x;
            while(x--)
            {
                cin>>s;
                a[s][i]=1;
            }
        }
        cin>>m;
        for(int i=1;i<=m;i++)
        {
            cin>>s;
            for(int j=1;j<n;j++)
            if(a[s][j]) cout<<j<<" ";
            if(a[s][n]) cout<<n;
            cout<<endl; 
        }
    }
}
int main()
{
    _mzf::mzfmain(); 
    return 0;
}

二维map骗90,爽

 

上一篇:OJ 11007 组合数


下一篇:[噼昂!]叕是斯特林数