Codeforces Round #673 (Div. 2) C. k-Amazing Numbers(思维)
You are given an array a consisting of n integers numbered from 1to n .
Let's define the k -amazing number of the array as the minimum number that occurs in all of the subsegments of the array having length k (recall that a subsegment of a of length k is a contiguous part of a containing exactly k elements). If there is no integer occuring in all subsegments of length k for some value of k , then the k -amazing number is -1 .
For each k from 1 to n calculate the k -amazing number of the array a .
Input
The first line contains one integer t (1≤t≤1000) — the number of test cases. Then t test cases follow.
The first line of each test case contains one integer n (1≤n≤3⋅105) — the number of elements in the array. The second line contains n integers a1,a2,…,an (1≤ai≤n) — the elements of the array.
It is guaranteed that the sum of n over all test cases does not exceed 3⋅105.
Output
For each test case print n integers, where the i -th integer is equal to the i -amazing number of the array.
Example
Input
Copy
3
5
1 2 3 4 5
5
4 4 4 4 2
6
1 3 1 5 3 1
Output
Copy
-1 -1 3 2 1
-1 4 4 4 2
-1 -1 1 1 1 1
暴力求显然不行。看到每个数的范围都在1~n故考虑根据每个不同的ai来计算对最终答案的贡献。注意到对于相同的数字,设d[x]为所有相邻x之间距离的最大值,特别的,计算的时候令第0个数字和第n + 1个数字都为x,那么对于取值为d[x], d[x] + 1, d[x] + 2 ... n的k,x都是amazing number。
例如对于数列1 3 1 5 3 1, 若x为1, 那么d[x] = d[1] = 3(1 5 3 1中两个1认为距离为3),那么k = 3, 4, 5时amazing number都为1(最小)。
具体写的话可以开一个数组last, last[i]代表i这个数字上一次出现的位置, k[i]表示k取值为i时候的amazing number。遍历一遍数列求出d数组,然后从小到大遍历1~n(桶的思想),如果d[i]值非0(说明i出现在数列中),更新当前没有赋值的k[d[i]], k[d[i] + 1]...k[n],因为是从小到大遍历,如果k已经被赋值,说明肯定是被更小的元素更新了,由题意自然就不必再更新。
#include <bits/stdc++.h>
using namespace std;
int n, a[300005], d[300005]/*d[i]表示相同i之间的最大距离*/, last[300005], k[300005];
//只能覆盖比最大距离大的段
int main()
{
int t;
cin >> t;
while(t--)
{
cin >> n;
memset(d, 0, sizeof(d));
memset(last, 0, sizeof(last));
memset(k, 0, sizeof(k));
for(int i = 1; i <= n; i++) cin >> a[i];
for(int i = 1; i <= n; i++)
{
d[a[i]] = max(d[a[i]], i - last[a[i]]);
last[a[i]] = i;
}
for(int i = 1; i <= n; i++)
{
if(last[i]) d[i] = max(d[i], n + 1 - last[i]);
}
for(int i = 1; i <= n; i++)
{
if(!d[i]) continue;
for(int j = d[i]; j <= n; j++)
{
if(k[j]) break;
k[j] = i;
}
}
for(int i = 1; i <= n; i++)
{
if(k[i]) cout << k[i] << ' ';
else cout << - 1 << ' ';
}
cout << endl;
}
return 0;
}