PAT (Advanced Level) Practice 1078 Hashing (25 分)
阿新 • • 發佈:2018-11-26
雜湊表二次探測法,即一次判斷(p+k2)%n,k=0…n-1,到n-1就可以了,因為之後會出現迴圈,證明的話就是:(n+i)2%n=(n2+2*n*i+i2)%n=i2%n
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=1e5+5;
int prime[N],pnum,notp[N],vis[N],revis[N];
void sieve()
{
for(int i=2;i<N;i++)
{
if(!notp[i]) prime[pnum++]=i;
for(int j=0;j<pnum&&prime[j]*i<N;j++)
{
notp[prime[j]*i]=1;
if(i%prime[j]==0) break;
}
}
}
int main()
{
sieve();
int sz,n;
scanf("%d%d",&sz,&n);
sz=prime[lower_bound(prime, prime+pnum,sz)-prime];
for(int i=1;i<=n;i++)
{
int x;scanf("%d",&x);
if(i!=1) printf(" ");
int flag=0;
for(int j=0;;j++)
{
int xx=(x+1LL*j*j)%sz;
if(!vis[xx])
{
vis[xx]=1;
printf( "%d",xx);
flag=1;
break;
}
if(revis[xx]==i) break;
revis[xx]=i;
}
if(!flag) printf("-");
}
return 0;
}