#雜湊,Pollard-Rho#JZOJ 6468 魚貫而入
阿新 • • 發佈:2021-07-12
雜湊,Pollard-Rho
內除以最小質因子小於\(n\)的數即可
這個定址的存放直接在原來的雜湊基礎上再開一個雜湊表,相當於是把\((x',x)\)裝進新的雜湊表中,
這樣就可以做到\(O(n^2A^{0.25}+n^3log_2A)\),但是比較卡常數,4s內勉強卡過
題目
有\(n\)個數\(a_i\),現將其依次插入大小為\(len\)的雜湊表中,
問如何選擇\(n\)使得定址時間最大,求最大定址時間
\(n\leq 200,len\geq n,a_i\leq 10^{18}\)
分析
讓其定址時間最大就是讓它在模意義下重複次數儘量多,
重複當且僅當\(len|abs(a_i-a_j)\),作差是最難想的,
等於是讓len為\(abs(a_i-a_j)\)的約數即可,
那麼這樣的約數實際上有\(O(n^2\sqrt{A})\)個
考慮如果\(len\)可行那麼,\(k*len\)不會更優,所以大於\(n^2\)的合數不會更優,
即只要判斷大於\(n^2\)的質數以及\([n,n^2]\)
這個定址的存放直接在原來的雜湊基礎上再開一個雜湊表,相當於是把\((x',x)\)裝進新的雜湊表中,
這樣就可以做到\(O(n^2A^{0.25}+n^3log_2A)\),但是比較卡常數,4s內勉強卡過
程式碼
#include <cstdio> #include <cctype> #include <cmath> #include <algorithm> #include <cstdlib> #define rr register using namespace std; typedef long long lll; const int N=40009; const double ha=pow(11.0,19/17.0); const int Prime[8]={2,61,97,7,13,17,23,29}; int prime[N],n,_h[N],ans,_n,m,v[N],Cnt,tot; lll o[N],h[N],B[N],b[N],a[N],H[N]; inline lll iut(){ rr lll ans=0; rr char c=getchar(); while (!isdigit(c)) c=getchar(); while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar(); return ans; } inline lll mo(lll a,lll b,lll mod){return a+b>=mod?a+b-mod:a+b;} inline lll mul(lll a,lll b,lll mod){return (a*b-(lll)((long double)a/mod*b)*mod+mod)%mod;} inline lll gcd(lll a,lll b){return b?gcd(b,a%b):a;} inline lll ksm(lll x,lll y,lll mod){ rr lll ans=1; for (;y;y>>=1,x=mul(x,x,mod)) if (y&1) ans=mul(ans,x,mod); return ans; } inline bool mr(lll n){ if(n==46856248255981ll||n<2) return 0; if(n==2||n==3||n==7||n==61||n==24251) return 1; if (!(n&1)||!(n%3)||!(n%7)||!(n%61)||!(n%24251)) return 0; rr lll m=n-1; rr int cnt=0; while (!(m&1)) m>>=1,++cnt; for (rr int i=0;i<5&&Prime[i]<n;++i){ rr lll now=ksm(Prime[i],m,n),ls=now; for (rr int j=1;j<=cnt;++j){ now=mul(now,now,n); if (now==1&&ls!=1&&ls!=n-1) return 0; ls=now; } if (now!=1) return 0; } return 1; } inline lll rho(lll n,lll h){ if (!(n&1)) return 2; if (!(n%3)) return 3; rr lll x1=(rand()+1)%n,x2=x1,p=1; for (rr int k=2;;k<<=1,x2=x1,p=1){ for (rr int i=1;i<=k;++i){ x1=mo(mul(x1,x1,n),h,n); p=mul(p,x1>x2?x1-x2:x2-x1,n); if (!(i&127)){ rr lll d=gcd(p,n); if (d>1) return d; } } rr lll d=gcd(p,n); if (d>1) return d; } } inline void dfs(lll n){ if (n==1) return; if (mr(n)){ B[++B[0]]=n; return; } rr lll t=n; while (t==n) t=rho(n,rand()%(n-1)+1); while (!(n%t)) n/=t; dfs(t),dfs(n); } inline signed locate(lll x){ rr int j=x%N; while (h[j]!=-1&&h[j]!=x) j=(j+1)%N; return j; } inline void answ(lll mod){ rr int sum=0; _h[0]=0; for (rr int i=1;i<=n;++i){ for (rr lll j=o[i]%mod;;j=(j+1)%mod,++sum){ rr int t=locate(j); if (h[t]==-1){ H[t]=o[i],h[t]=j, _h[++_h[0]]=t; break; } if (H[t]==o[i]) break; } } for (rr int i=1;i<=_h[0];++i) h[_h[i]]=H[_h[i]]=-1; if (ans<sum) ans=sum; } signed main(){ freopen("hash.in","r",stdin); freopen("hash.out","w",stdout); iut(),n=iut(),srand(N); for (rr int i=0;i<N;++i) h[i]=-1; for (rr int i=1;i<=n;++i) o[i]=a[i]=iut(); sort(a+1,a+1+n),m=unique(a+1,a+1+n)-a-1,_n=n*n,v[1]=1; for (rr int i=2;i<=_n;++i){ if (!v[i]) v[i]=prime[++Cnt]=i; for (rr int j=1;j<=Cnt&&prime[j]*i<=_n;++j){ v[i*prime[j]]=prime[j]; if (i%prime[j]==0) break; } } for (rr int i=1;i<m;++i) for (rr int j=i+1;j<=m;++j) { B[0]=0,dfs(a[j]-a[i]); for (rr int k=1;k<=B[0];++k) if (B[k]>n*n) b[++tot]=B[k]; } sort(b+1,b+1+tot),tot=unique(b+1,b+1+tot)-b-1; for (rr int i=1;i<=tot;++i) answ(b[i]); for (rr int i=n;i<=_n;++i) if (i/v[i]<n) answ(i); return !printf("%d",ans); }