Another GCD question
Title link: nowcoder 213804
To Niu Ke:
Topic
Give you an array and ask you to find 2 ∼ n 2\sim n from them2∼The maximum value of n gcds.
Ideas
Seeing this question, we consider how many numbers have xxThe factor of x , let it befx f_xfx。
Then we decompose the prime factors (use prime number screening and floor(sqrt()) to speed up), and then dfs, you can get each factor of a number, and then get fx f_xfx。
With this, we can ask to choose yyWhat is the maximum gcd of the y number?
(That is to search the firstfi f_ifrom back tofrontfiGreater than or equal to yyy number)
Then we can first figure out which is just yyy number, and then run the maximum value from back to front.
Then you can get the answer.
The specific implementation can look at the code.
Code
#include<cmath>
#include<cstdio>
#include<iostream>
using namespace std;
int n, a[100001], su[50001], all[100001], tmpn, tmp, ans[100001], maxn, zyz[1001], numm[1001];
bool susu[100100];
void getsusu() {
//素数筛选法筛出素数
susu[1] = susu[0] = 1;
for (int i = 2; i <= maxn + 100; i++)
if (!susu[i]) {
su[++su[0]] = i;
for (int j = i + i; j <= maxn + 100; j += i)
susu[j] = 1;
}
}
void dfs(int now, int sum) {
if (now == zyz[0] + 1) {
all[sum]++;
return ;
}
int tmpp = 1;
for (int i = 0; i <= numm[now]; i++) {
//对于这一个因数,选多少个乘
dfs(now + 1, sum * tmpp);
tmpp *= zyz[now];
}
}
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
maxn = max(maxn, a[i]);
ans[i] = 1;
}
getsusu();
for (int i = 1; i <= n; i++){
zyz[0] = 0;//分解质因数
tmpn = a[i];
tmp = floor(sqrt(a[i]));
for (int j = 1; su[j] <= tmpn && j <= tmp; j++) {
if (tmpn % su[j] == 0) {
zyz[++zyz[0]] = su[j];
numm[zyz[0]] = 0;
while (tmpn % su[j] == 0) {
numm[zyz[0]]++;
tmpn /= su[j];
}
}
}
if (tmpn != 1) {
zyz[++zyz[0]] = tmpn;
numm[zyz[0]] = 1;
}
dfs(1, 1);//标记每一个因数
}
for (int i = maxn; i >= 1; i--) {
if (ans[all[i]] == 1) ans[all[i]] = i;
}
for (int i = n - 1; i >= 2; i--)//选 i 个也可以在 i+x 个中选 i 个,不一定要刚刚好
ans[i] = max(ans[i + 1], ans[i]);
for (int i = 2; i <= n; i++) printf("%d ", ans[i]);
return 0;
}