哈希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\n");
        else                         printf("No\n");
    }
    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\n",cnt,res);
    }
    return 0;
}

...

posted @ 2019-10-31 11:41  逆天峰  阅读(199)  评论(0编辑  收藏  举报
作者:逆天峰
出处:https://www.cnblogs.com/gcfer//