A. k-Amazing Numbers
You are given an array a consisting of n integers numbered from 1 to 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
3
5
1 2 3 4 5
5
4 4 4 4 2
6
1 3 1 5 3 1
output
-1 -1 3 2 1
-1 4 4 4 2
-1 -1 1 1 1 1
题意:输入一串数组a,它由n个1到n的整数组成,k-Amazing Numbers就是这个数组中所有长度为k的连续子串中包含的最小的数字,如果没有都包含的数字,那么k-Amazing Numbers为-1。
分析:其实理解了题目意思之后,题目就变得清晰了很多,如果一个数是k-Amazing Numbers,那么每两个这个数字的最长的间隔需要小于等于k。所以我们需要枚举一个数和序列开头,中间数之间的差,最后一个数和序列结尾的最大值,就是这个数的最长的间隔。用ans[k]代表间隔为k的最小的数字。接下来,还需要更新一次ans数组,因为间隔长度小的数也一定能覆盖间隔长度大的。
详细见代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#define INF 0x3f3f3f3f
using namespace std;
int a[300005];
vector<int>p[300005];
int ans[300005];
int main()
{
int t;
scanf("%d",&t);
while(t--){
int n;
scanf("%d",&n);
for(int i=0;i<=n;i++){
p[i].clear();
ans[i]=INF;
}
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
p[a[i]].push_back(i);//存每个数字出现的每一个位置
}
for(int i=1;i<=n;i++){//遍历n个数字
if(!p[i].empty()){
int t=0;
for(int j=1;j<p[i].size();j++)
t=max(t,p[i][j]-p[i][j-1]);//计算出最大的间隔
t=max(max(t,p[i].front()-1+1),n-p[i].back()+1);//该数出现的第一个位置和序列首端的间隔和该数出现的最后一个位置和序列末端的间隔的最大值
ans[t]=min(ans[t],i);//记录间隔为t的最小数字
}
}
for(int i=2;i<=n;i++)ans[i]=min(ans[i],ans[i-1]);//间隔长度小的数也一定能覆盖间隔长度大的。
for(int i=1;i<=n;i++){
if(ans[i]==INF)printf("-1 ");
else printf("%d ",ans[i]);
}
printf("\n");
}
return 0;
}