字符串哈希&二维数组哈希&哈希表


#include<iostream>
#include<chrono>

using namespace std;

namespace IO{
    struct INID{INID(){ios::sync_with_stdio(false);cin.tie(nullptr);}};
    static INID INI_D;
    inline int gc(){return cin.rdbuf()->sbumpc();}
    inline void pc(char c){cout.rdbuf()->sputc(c);}
    template<typename T>inline void rd(T& x){
        x=0;int f=1,c=gc();
        while('0'>c||c>'9'){if(c==EOF){cerr<<"IIE\n";exit(EXIT_FAILURE);}if(c=='-'){f*=-1;}c=gc();}   
        while('0'<=c&&c<='9'){x=x*10+c-'0';c=gc();}
        x*=f;   
    }
    template<typename T>inline void wt(T x){
        if(x<0)pc('-');
        static int stk[40],tp;
        do{stk[++tp]=(x%10<0?-x%10:x%10)+'0';x/=10;}while(x);
        while(tp)pc(stk[tp--]);
    }
}
using namespace IO;

typedef long long ll;
typedef unsigned long long ull;
constexpr int inf=0x3f3f3f3f;

namespace HASH{
    constexpr int base1=131;
    constexpr int base2=13331;
    constexpr int mod1=1e9+7;
    constexpr int mod2=1e9+9;

    struct Hash{
        constexpr static int N=1e6+5;//字符串长度
        int h1[N];
        int h2[N];
        int p1[N];
        int p2[N];
        int sz;
        inline void initp(int _n){
            sz=_n;
            p1[0]=p2[0]=1;
            h1[0]=h2[0]=0;
            for(int i=1;i<=sz;++i){
                p1[i]=(ll)p1[i-1]*base1%mod1;
                p2[i]=(ll)p2[i-1]*base2%mod2;
            }
        }
        inline void inith(const string& s){
            for(int i=1;i<=s.length();++i){
                h1[i]=((ll)h1[i-1]*base1+s[i-1])%mod1;
                h2[i]=((ll)h2[i-1]*base2+s[i-1])%mod2;
            }
        }
        inline int hash1(int l,int r){
            return ((ll)h1[r]-(ll)h1[l-1]*((p1[r-l+1]))%mod1+mod1)%mod1;
        }
        inline int hash2(int l,int r){
            return ((ll)h2[r]-(ll)h2[l-1]*((p2[r-l+1]))%mod2+mod2)%mod2;
        }
        inline ull hsh(int l,int r){
            return (ull)hash1(l,r)<<32|hash2(l,r);
        }
        inline ull strHsh(const string& s){
            ull ret1=0,ret2=0;
            for(int i=1;i<=s.length();++i){
                ret1+=p1[i]*s[i]%mod1;
                ret2+=p2[i]*s[i]%mod2;
            }
            return ret1<<32|ret2;
        }
    }hs;

    struct Hash2D{
        constexpr static int N=1005;
        constexpr static int M=1005;
        int h1[N][M];
        int h2[N][M];
        int pr1[N];
        int pr2[N];
        int pc1[M];
        int pc2[M];
        int szn,szm;
        template<size_t T1,size_t T2>
        inline void init(const int (&a)[T1][T2],int _n,int _m){
            szn=_n;
            szm=_m;
            pr1[0]=pr2[0]=1;
            pc1[0]=pc2[0]=1;
            h1[0][0]=h2[0][0]=0;
            for(int i=1;i<=szm;++i){
                h1[0][i]=h2[0][i]=0;
                pc1[i]=(ll)pc1[i-1]*base1%mod1;
                pc2[i]=(ll)pc2[i-1]*base1%mod2;
            }
            for(int i=1;i<=szn;++i){
                h1[i][0]=h2[i][0]=0;
                pr1[i]=(ll)pr1[i-1]*base2%mod1;
                pr2[i]=(ll)pr2[i-1]*base2%mod2;
            }
            for(int i=1;i<=szn;++i){
                for(int j=1;j<=szm;++j){
                    h1[i][j]=((ll)h1[i][j-1]*base1+a[i][j])%mod1;
                    h2[i][j]=((ll)h2[i][j-1]*base1+a[i][j])%mod2;
                }
            }
            for(int j=1;j<=szm;++j){
                for(int i=1;i<=szn;++i){
                    h1[i][j]=((ll)h1[i-1][j]*base2+h1[i][j])%mod1;
                    h2[i][j]=((ll)h2[i-1][j]*base2+h2[i][j])%mod2;
                }
            }
        }
        inline int hash1(int x1,int y1,int x2,int y2){
            //x是行,y是列
            ll A=(h1[x2][y2]-((ll)h1[x1-1][y2]*pr1[x2-x1+1]%mod1))%mod1;
            ll B=(h1[x2][y1-1]-((ll)h1[x1-1][y1-1]*pr1[x2-x1+1]%mod1))%mod1;
            return ((A-B*pc1[y2-y1+1])%mod1+mod1)%mod1;
        }
        inline int hash2(int x1,int y1,int x2,int y2){
            //x是行,y是列
            ll A=(h2[x2][y2]-((ll)h2[x1-1][y2]*pr2[x2-x1+1]%mod2))%mod2;
            ll B=(h2[x2][y1-1]-((ll)h2[x1-1][y1-1]*pr2[x2-x1+1]%mod2))%mod2;
            return ((A-B*pc2[y2-y1+1])%mod2+mod2)%mod2;
        }
        inline ull hsh(int x1,int y1,int x2,int y2){
            return (ull)hash1(x1,y1,x2,y2)<<32|hash2(x1,y1,x2,y2);
        }
    }hs2;

    struct HashTable{
        constexpr static int N=1e6+5;//元素数
        int keyCnt;
        struct table{
            int sz;
            struct edge{
                int nxt,val;
                ull key;
            };
            edge e[N];
            int hdE[N],cntE;
            inline void addE(int u,int val,ull key){
                e[++cntE]={hdE[u],val,key};
                hdE[u]=cntE;
            }
            inline void init(int _n=N-1){
                sz=_n;
                cntE=0;
                for(int i=0;i<_n;++i){
                    hdE[i]=0;
                }
            }
        };
        table tb;
        inline void init(int _n=N-1){
            tb.init(_n);
            keyCnt=0;
        }
        inline ull hsh(ull key){
            const static ull seed=chrono::steady_clock::now().time_since_epoch().count();
            const static ull C=0x9e3779b97f4a7c15ull;
            ull x=key+seed+C;
            x^=x>>30;
            x*=C;
            x^=x>>27;
            x*=C;
            x^=x>>31;
            x*=C;
            return x;
        }
        inline void ins(ull key,int val){
            ++keyCnt;
            int u=hsh(key)%tb.sz;
            tb.addE(u,val,key);
        }
        inline void dlt(ull key,int val){
            int u=hsh(key)%tb.sz;
            int pre=0;
            for(int i=tb.hdE[u];i;i=tb.e[i].nxt){
                if(tb.e[i].key==key&&tb.e[i].val==val){
                    if(pre)tb.e[pre].nxt=tb.e[i].nxt;
                    else tb.hdE[u]=tb.e[i].nxt;
                    --keyCnt;
                    return ;
                }
                pre=i;
            }
        }
        inline void modify(ull key,int val,int newVal){
            int u=hsh(key)%tb.sz;
            for(int i=tb.hdE[u];i;i=tb.e[i].nxt){
                if(tb.e[i].key==key&&tb.e[i].val==val){
                    tb.e[i].val=newVal;
                    return ;
                }
            }
            ins(key,newVal);
        }
        inline int findMin(ull key){
            int u=hsh(key)%tb.sz;
            int mn=inf;
            for(int i=tb.hdE[u];i;i=tb.e[i].nxt){
                if(tb.e[i].key==key){
                    mn=min(mn,tb.e[i].val);
                }
            }
            return mn;
        }
        inline int findMax(ull key){
            int u=hsh(key)%tb.sz;
            int mx=-inf;
            for(int i=tb.hdE[u];i;i=tb.e[i].nxt){
                if(tb.e[i].key==key){
                    mx=max(mx,tb.e[i].val);
                }
            }
            return mx;
        }
        inline int find(ull key,int val){
            int u=hsh(key)%tb.sz;
            for(int i=tb.hdE[u];i;i=tb.e[i].nxt){
                if(tb.e[i].key==key&&tb.e[i].val==val){
                    return 1;
                }
            }
            return -inf;
        }
    }hst;
}
using namespace HASH;


int n;

inline void global(){

}



namespace tqy{
    inline void init(){
        rd(n);
        hst.init(n);
        hs.initp(1505);
        for(int i=1;i<=n;++i){
            string s;
            cin>>s;
            ull t=hs.strHsh(s);
            hst.modify(t,1,1);
        }  
    }
    inline void solve(){
        wt(hst.keyCnt);
        pc('\n');
    }
}

signed main(){
    global();
    int T=1;
    while(T--)tqy::init(),tqy::solve();
    return 0;
}
/*

*/
posted @ 2026-10-23 11:02  tqytql  阅读(6)  评论(0)    收藏  举报