思路
对于每个数,考虑相同数之间最少需要多长的k才能将其涵盖。枚举一个数与序列开头、中间数之间的差和序列结尾,过程中记录长度k范围内最小的数值。
代码
#include<map>
#include<set>
#include<stack>
#include<queue>
#include<string>
#include<math.h>
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#define pb push_back
using namespace std;
const int maxn=1e6+5;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int minn=0xc0c0c0c0;
vector<int>s[maxn];
int n,t,x,a[maxn];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin>>t;
while(t--)
{
cin>>n;
for(int i=0;i<=n;i++)
{
a[i]=inf;
s[i].clear();
}
for(int i=1;i<=n;i++)
{
cin>>x;
s[x].pb(i);//x出现的位置
}
for(int i=1;i<=n;i++)
{
if(!s[i].empty())
{
int tmp=0;
for(int j=1;j<s[i].size();j++)
tmp=max(tmp,s[i][j]-s[i][j-1]);//i出现的相邻位置的最大间距
tmp=max(tmp,s[i].front());
tmp=max(tmp,n-s[i].back()+1);
a[tmp]=min(a[tmp],i);//至多tmp的长度覆盖的范围中最小的数字
}
}
for(int i=2;i<=n;i++)
a[i]=min(a[i],a[i-1]);//更新前缀和,小区间可覆盖的大区间一定可以
for(int i=1;i<=n;i++)
{
if(a[i]!=inf)
cout<<a[i]<<" ";
else
cout<<"-1"<<" ";
}
cout<<endl;
}
return 0;
}