标签:10 last int 多校 ret 牛客 seed 2021 getchar
H题: Hash Function
原题链接:https://ac.nowcoder.com/acm/contest/11166/H
题目大意
给定一个大小为
n
(
1
≤
n
≤
5
⋅
1
0
10
)
n(1≤n≤5·10^{10} )
n(1≤n≤5⋅1010)的集合
S
=
{
a
0
,
a
1
,
.
.
.
,
a
n
−
1
}
S=\{a_0,a_1,...,a_{n-1}\}
S={a0,a1,...,an−1}。
求最小的正整数
s
e
e
d
seed
seed,使得对于任意
i
(
0
≤
i
<
n
)
i(0\leq i<n)
i(0≤i<n),
a
i
m
o
d
s
e
e
d
a_i\bmod seed
aimodseed的结果各不相同。
题解
数据强度一般,采用优化版暴力做法。
因为有
n
n
n个数据,所以哈希域的大小应不小于
n
n
n,从
n
n
n开始往上枚举
s
e
e
d
seed
seed,对于每个
s
e
e
d
seed
seed进行判断。
对时间复杂度进行优化,不难发现,因为我们枚举的
s
e
e
d
seed
seed是不断增大的,所以当一个数已经小于当前的
s
e
e
d
seed
seed时,对于以后的任意一个更大的
s
e
e
d
seed
seed,取模结果都是该数本身,即在以后的判断过程中,我们不需要对该数的取模结果进行计算。我们可以通过对数组进行排序,以优化初始化过程
参考代码
#include<bits/stdc++.h>
using namespace std;
const int MAXN=5e5+5;
int n,a[MAXN],t=1;
int vis[MAXN];
void read(int &x){
int ret=0;
char c=getchar(),last;
while(c<'0'||c>'9')last=c,c=getchar();
while(c>='0'&&c<='9'){
ret=ret*10+c-'0';
c=getchar();
}
x=last=='-'?-ret:ret;
}//读入优化
bool check(int mod){
for(int i=t;i<=n;i++){
if(a[i]<mod&&vis[i]==0)vis[a[i]]=-1,t=i+1;//对于小于mod的数进行特殊标记,并记录下标,优化判断时的起始位置
else if(vis[a[i]%mod]==0)vis[a[i]%mod]=1;//对于不小于mod的数计算取模值并标记
else if(vis[a[i]%mod])//发现两数取模值相同
{
for(int j=t;j<i;j++)if(vis[a[j]%mod]!=-1)vis[a[j]%mod]=0;//将普通标记初始化
return false;
}
}
return true;
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)read(a[i]);
sort(a+1,a+n+1);//排序
for(int i=n;;i++)if(check(i)){printf("%d\n",i);break;}//枚举,判断
return 0;
}
标签:10,last,int,多校,ret,牛客,seed,2021,getchar 来源: https://blog.csdn.net/Spy_Savior/article/details/118862248
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。