[Nowcoder 213804] Another GCD problem

Another GCD question

Title link: nowcoder 213804

To Niu Ke:

——>Click me to jump<——

Topic

Give you an array and ask you to find 2 ∼ n 2\sim n from them2The 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;
}

Guess you like

Origin blog.csdn.net/weixin_43346722/article/details/112740731
gcd