链接:https://ac.nowcoder.com/acm/contest/10743/B
来源:牛客网
题目描述
给出 n 个数 a_1\sim a_na
1
∼a
n
,对每个 i\in [2,n]i∈[2,n],求出从他们中选出 i 个的 gcd 的最大值。
输入描述:
第一行一个正整数 n。
接下来 n 个正整数 a_1\sim a_na
1
∼a
n
。
保证 2\le n\le 10^52≤n≤10
5
,1\le a_i\le 10^51≤a
i
≤10
5
。
输出描述:
n-1 个正整数,第 i 个为选出 i+1 个的 gcd 的最大值。
示例1
输入
复制
5
1 2 3 4 6
输出
复制
3 2 1 1
关键的枚举的顺序
与其枚举几个数,看他们的最大公约数是多少,还不如直接看一个数是多少个数的公约数,求出那个最大的。
坑点:5个数是同一个数的倍数,那么一定可以找到4个数是这个数的倍数
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1e5 + 10;
int n;
int st[N];
int ans[N];
int a[N];
int main(){
scanf("%d", &n);
int maxd = 0;
for (int i = 1; i <= n; i ++){
scanf("%d", &a[i]);
maxd = max(maxd, a[i]);
st[a[i]] ++;
}
for (int i = 1; i <= n; i ++) ans[i] = 1;
for (int i = maxd; i >= 1; i --){
int cnt = 0;
for (int j = i; j <= maxd; j += i){
cnt += st[j];
}
for (int k = cnt; k >= 1; k --) ans[k] = max(ans[k], i);
}
for (int i = 2; i <= n; i ++)
cout << ans[i] << " ";
cout << endl;
return 0;
}