哈希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; }
...