HDU 6098 Inversion (序列变换)

Description

给出数组A,下标从\(1\)开始,求数组B

\[B_i=\max_{i \nmid j} A_j, i \leqslant 2 \]

Input

第一行给出用例组数\(T\),对于每组用例,第一行给出A数组的长度,第二行给出\(n\)个数表示数组A的元素。\(T \leqslant 20\)\(2 \leqslant n \leqslant 10^5\)\(1 \leqslant A_i \leqslant 10^9\)

Output

对于每组用例,输出\(n-1\)个整数,分别表示\(B_2\)\(B_3\)\(\cdots\)\(B_n\)

Sample Input

2
4
1 2 3 4
4
1 4 2 3

Sample Output

3 4 3
2 4 4

Solution

典型的序列变换问题,数据规模是\(10^5\),显然最后复杂度为\(O(nlogn)\),这道题又涉及到整除,显然\(O(logn)\)就要来自于因子的个数。

设A数组中最大的数为\(A_k\),对于\(k\),它的因子只有\(\log n\)个,其余的\(n- \log n\)个数都不能整除\(k\),也就是B数组中的\(n-\log n\)个不能整除\(k\)的下标对应的值就是\(A_k\),对于\(k\)\(\log n\)个因子,每个因子扫描一遍A数组寻找满足条件的最大值即可。

Code

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int N = 1e5 + 10;

typedef pair<int, int> pii;
pii a[N];
int b[N];

int main()
{
	int T;
	scanf("%d", &T);
	while (T--)
	{
		int n;
		scanf("%d", &n);
		for (int i = 1; i <= n; i++) scanf("%d", &a[i].first), a[i].second = i;
		sort(a + 1, a + n + 1);
		for (int i = 2; i <= n; i++)
			for (int j = n; j >= 1; j--)
				if (a[j].second % i != 0)
				{
					b[i] = a[j].first;
					break;
				}
		for (int i = 2; i < n; i++) printf("%d ", b[i]);
		printf("%d\n", b[n]);
	}
	return 0;
}

http://acm.hdu.edu.cn/showproblem.php?pid=6098

posted @ 2017-08-13 09:18  达达Mr_X  阅读(256)  评论(0)    收藏  举报