• 哈希hash


    模板:

    inline int hash(int x) 
    {
        int o=x%p;
        while(vis[o]&&vis[o]!=x) ++o;
         return o;         
    }

    最简单的模板:

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int N=201100,p=201007;
    ll vis[N],n,c,a[N],num[N],cnt;
    inline ll read()
    {
        ll x=0,ff=1;
        char ch=getchar();
        while(!isdigit(ch)) {if(ch=='-') ff=-1;ch=getchar();}
        while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
        return x*ff;
    }
    inline ll hash(ll x)
    {
        ll o=x%p;
        while(vis[o]&&vis[o]!=x) ++o;
        return o;
    }
    int main()
    {
        //freopen("1.in","r",stdin);
        n=read();c=read();
        for(register int i=1;i<=n;++i)
        {
            a[i]=read();
            ll s=hash(a[i]+c);
            vis[s]=a[i]+c;num[s]++;
        }
        for(register int i=1;i<=n;++i)
        {
            ll s=hash(a[i]);
            if(vis[s]==a[i]) cnt+=num[s];
        }
        printf("%lld",cnt);
        return 0;
    }

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    const int N=101000,P=1e5+3; 
    ll a[N][7],n,pd;
    vector<ll>v[N];
    inline ll read()
    {
        ll x=0,ff=1;
        char ch=getchar();
        while(!isdigit(ch)) {if(ch=='-') ff=-1;ch=getchar();}
        while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
        return x*ff;
    }
    inline ll Hash(ll x)
    {
        ll ans1=0,ans2=1;
        for(int i=1;i<=6;++i) ans1=(ans1+a[x][i])%P,ans2=(ans2*a[x][i])%P;
        return (ans1+ans2)%P;
    } 
    inline bool equal(ll x,ll y)
    {
        for(int i=1;i<=6;++i) //枚举断点. 
        {
            int k=0,z=0;                                         //顺时针. 
            for(int j=i;j<=6;++j) if(a[x][j]!=a[y][++k]) z=1;
            for(int j=1;j<i;++j) if(a[x][j]!=a[y][++k]) z=1;
            if(!z) return 1;
            k=0,z=0;                                        //逆时针. 
            for(int j=i;j>=1;--j) if(a[x][j]!=a[y][++k]) z=1;
            for(int j=6;j>i;--j) if(a[x][j]!=a[y][++k]) z=1;
            if(!z) return 1; 
        }
        return 0;
    }
    inline void check(int x)
    {
        ll s=Hash(x);
        for(register int i=0;i<v[s].size();++i)
        {
            if(equal(v[s][i],x)) 
            {
                pd=1;
                return;
            }
        }
        if(!pd) v[s].push_back(x);
    }
    int main()
    {
    //    freopen("1.in","r",stdin); 
        n=read();
        for(register int i=1;i<=n;++i)
        {
            for(int j=1;j<=6;++j) a[i][j]=read();
            ll s=Hash(i);
            if(v[s].size()==0) v[s].push_back(i);
            else                  check(i);
            if(pd) 
            {
                printf("Twin snowflakes found.");
                return 0;
            }
        }
        printf("No two snowflakes are alike.");
        return 0;
    }

    今天做了几道字符串哈希:

    #include<bits/stdc++.h>
    #define ull unsigned long long
    using namespace std;
    const int N=1000000,base=131;
    ull h[N],p[N];
    int m;
    char str[N];
    inline int read()
    {
        int x=0,ff=1;
        char ch=getchar();
        while(!isdigit(ch)){if(ch=='-') ff=-1;ch=getchar();}
        while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
        return x*ff;
    }
    inline ull Hash(int l,int r){return (h[r]-h[l-1]*p[r-l+1]);}
    int main()
    {
        scanf("%s",str+1);
        int n=strlen(str+1);p[0]=1;
        for(register int i=1;i<=n;++i)
        {
            h[i]=h[i-1]*base+str[i]-'a'+1;
            p[i]=p[i-1]*base;
        }
        m=read();
        while(m--)
        {
            int l1=read(),r1=read();
            int l2=read(),r2=read();
            if(Hash(l1,r1)==Hash(l2,r2)) printf("Yes
    ");
            else                         printf("No
    ");
        }
        return 0;
    }

    #include<bits/stdc++.h>
    #define ull unsigned long long  
    using namespace std;
    const int N=2000100,base=131;
    ull hl[N],hr[N],p[N];
    char str[N];
    int cnt;
    inline int read()
    {
        int x=0,ff=1;
        char ch=getchar();
        while(!isdigit(ch)){if(ch=='-') ff=-1;ch=getchar();}
        while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
        return x*ff;
    }
    inline ull get1(int l,int r){return (hl[r]-hl[l-1]*p[r-l+1]);}
    inline ull get2(int l,int r){return (hr[r]-hr[l-1]*p[r-l+1]);}
    int main()
    {
    //    freopen("1.in","r",stdin);
        while(scanf("%s",str+1),strcmp(str+1,"END"))
        {
            cnt++;
            int n=strlen(str+1);
            for(int i=2*n;i>0;i=i-2)//将每两个字符中间插入‘27’ 
            {        
                str[i]=str[i/2];//先赋值 
                str[i-1]=27;//添加 
            }
            n=2*n;p[0]=1;//改变为新的字符串 
            for(register int i=1,j=n;i<=n;++i,--j)
            {
                hl[i]=hl[i-1]*base+str[i]-'a'+1;
                hr[i]=hr[i-1]*base+str[j]-'a'+1;
                p[i]=p[i-1]*base; 
            }
            int res=0;
            for(register int i=1;i<=n;++i)
            {
                int l=0,r=min(i-1,n-i);
                while(l<r)
                {
                    int mid=(l+r+1)>>1;
                    if(get1(i-mid,i-1)==get2(n+1-(i+mid),n+1-(i+1))) l=mid;
                    else r=mid-1; 
                }
                if(str[i-l]==27) res=max(res,((l<<1)+1)>>1);
                else             res=max(res,((l<<1)+1)-(((l<<1)+1)>>1));
            }
            printf("Case %d: %d
    ",cnt,res);
        }
        return 0;
    }

    ...

  • 相关阅读:
    在react中实现CSS模块化
    react 组件的生命周期
    HTTP缓存机制与原理
    H5新增API和操作DOM
    js操作json方法总结
    gulp详细教程——前端自动化构建工具
    JavaScript你必须掌握的8大知识点
    HTTP请求与服务器响应流程
    max-height实现任意高度元素的展开收缩动画
    移动端轮播图手势分析+源码
  • 原文地址:https://www.cnblogs.com/gcfer/p/11770310.html
Copyright © 2020-2023  润新知