Long time no see...时隔多月,终于又回来了....csdn大佬云集,study harder and make progress everyday...
You are given an array a consisting of n integers numbered from 1 to n. 给你一个数组a,存有n个数,从1~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). 让我们明确一下数组的k-Amazing Numbers (惊奇的数字)的定义,数组中所有长度为k的子序列都存在的一个最小数字,提醒一个长度为k的子序列是连续的且包含k个元素的一个序列
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.若所有长度为k的子序列不存在一个k值,那么输出-1,计算出a数组从1~n的k值
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.a1,a2,…,an (1≤ai≤n) 暗示可以枚举
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.输出n个数,第i个数对应的k值
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
题意: 具体的就看看上面,(锻炼一下翻译能力,太弱了,有时候只能自己懂...害,多写写吧,,)
大概就是t组数据,然后一个n,每组n个数据;输出n个数,每个数对应的k-amazing值,k-amazing值是这个数组所有长度为k所覆盖的子序列里最小的那个数值。
分析:用vector容器v[ ]数组存一下每个值之间距离的最大值,(每个值在数组的第0位和n+1位也赋虚拟的值),然后用ans数组(初始化为inf)储存一下每个距离能覆盖的最小数字,(其中需要两次更新,一次是在不断更新算过的间距值,可能这个间距里会出现更小的数字;二次是在前缀和更新计算过的最小数字).....具体见代码吧...
Code:
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=3*1e5+10;
#include<math.h>
#define inf 0x3f3f3f3f
#include<vector>
vector<ll>v[N];/// 每个值的位置
ll ans[N];///间距为i的子序列存在的最小数字
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
for(ll i=0; i<=n; i++)///初始化
{
ans[i]=inf;
v[i].clear();
}
ll x;
for(ll i=1; i<=n; i++)
{
scanf("%lld",&x);
v[x].push_back(i);///相同值的位置坐标存进去
}
// for(int i=1;i<=n;i++)
// {
// if(!v[i].empty())
// {
// printf("%lld ___ %lld\n",v[i].front(),v[i].back());///首 尾
// }
// }
for(ll i=1; i<=n; i++)
{
if(!v[i].empty())
{
ll mx=0;
for(ll j=1; j<v[i].size(); j++)/// 0~v[i].size()
{
mx=max(mx,v[i][j]-v[i][j-1]);///中间间距找最大
}
mx=max(mx,v[i].front());///首
mx=max(mx,n-v[i].back()+1);///尾
ans[mx]=min(ans[mx],i);/// 间距为mx的最小数字 update
}
}
for(ll i=2; i<=n; i++)///前缀和处理一下 因为2能覆盖的 后面肯定也能覆盖
///update to find the mininum
{
ans[i]=min(ans[i],ans[i-1]);
}
for(ll i=1; i<=n; i++)
{
if(ans[i]<inf)///没有找到k-mazing值 print -1
printf("%lld%c",ans[i],i==n?'\n':' ');
else printf("-1%c",i==n?'\n':' ');
}
}
return 0;
}
队列写---题意会了,啥都能写~一开始咋写咋不过,第一个代码过了之后,队列写的就改了几处细节,就Accepted了
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=3*1e5+10;
#include<math.h>
#define inf 0x3f3f3f3f
#include<queue>
#include<vector>
queue<int>q[N];
int a[N];
int dist[N];/// 1<=ai<=n 记录每
int ans[N];
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d",&n);
for(int i=1; i<=n; i++)///初始化
{
dist[i]=0;
a[i]=0;
ans[i]=inf;
// q[i].clear();
while(!q[i].empty())
q[i].pop();
}
for(int i=1; i<=n; i++)
{
scanf("%d",&a[i]);
q[a[i]].push(i);///记录每个相同值的下标
}
// for(int i=1;i<=n;i++)
// {
// if(!q[i].empty())
// {
// printf("%d ___ %d \n",q[i].front(),q[i].back());
// }
// }
for(int i=1; i<=n; i++)
{
while(!q[i].empty())
{
int x1=q[i].front();
q[i].pop();
int maxx=x1;
int y=x1;///end
while(!q[i].empty())
{
int x2=q[i].front();
q[i].pop();
maxx=max(maxx,x2-y);
y=x2;
}
// dist[i]=max(maxx,n+1-y);
dist[i]=max(maxx,n-q[i].back()+1);
ans[dist[i]]=min(ans[dist[i]],i);
}
}
for(int i=2;i<=n;i++)
{
ans[i]=min(ans[i-1],ans[i]);
}
for(int i=1; i<=n; i++)
{
if(ans[i]<inf)
printf("%d%c",ans[i],i==n?'\n':' ');
else
printf("-1%c",i==n?'\n':' ');
}
}
return 0;
}
划水会上瘾...可是 努力也会...
还有几天就20岁了...How time flies?!