原题
Problem Statement
You are given a sequence
A
=
(
A
1
,
A
2
,
…
,
A
N
)
A = (A_1, A_2, \dots, A_N)
A=(A1,A2,…,AN) of length NN and a positive integer
K
K
K (at most
N
N
N).
For each
i
=
1
,
2
,
…
,
N
i = 1, 2, \dots, N
i=1,2,…,N solve the following problem:
When you choose
K
K
K elements from
A
A
A that include
A
i
A_i
Ai, find the maximum possible GCD (greatest common divisor) of those chosen elements.
Constraints
1
≤
K
≤
N
≤
1.2
×
1
0
6
1 \leq K \leq N \leq 1.2 \times 10^6
1≤K≤N≤1.2×106
1
≤
A
i
≤
1
0
6
1 \leq A_i \leq 10^6
1≤Ai≤106
All input values are integers.
思路
这道题,很显然每个数与它的倍数和因数可以组成一组,对于每个数统计倍数即可。
先拿一个桶,统计每个数出现过几次。然后枚举范围内的每个数,将对于它们来说,数组中出现过的倍数的个数给记录下来就可以了。
然后将存答案的数组初始化为
1
1
1。再次枚举范围内的每一个数以及倍数。如果它的倍数个数大于了
k
k
k。说明可以组成一组。于是更新它及倍数的最大的最小公约数就可以了。
这个问题的时间复杂度显然是一个调和级数,复杂度是
O
(
N
l
o
g
N
)
O(NlogN)
O(NlogN) 的,能过。
Code
#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,a[2145140],t[2145140],ans[2145140],b[2145140],mx,k;
signed main(){
cin>>n>>k;
for(int i=1;i<=n;i++){
cin>>a[i];
mx=max(mx,a[i]);
t[a[i]]++;
}
for(int i=1;i<=mx;i++){
for(int j=1;j<=mx/i;j++){
b[i]+=t[i*j];
}
}
for(int i=1;i<=mx;i++) ans[i]=1;
for(int i=1;i<=mx;i++){
if(b[i]>=k){
for(int j=1;j<=mx/i;j++){
ans[i*j]=max(ans[i*j],i);
}
}
}
for(int i=1;i<=n;i++){
cout<<ans[a[i]]<<endl;
}
}