Bellovin
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 354 Accepted Submission(s): 178
Problem Description
Peter has a sequence
a1,a2,...,an
and he define a function on the sequence --
F(a1,a2,...,an)=(f1,f2,...,fn)
, where
fi
is the length of the longest increasing subsequence ending with
ai
.
Peter would like to find another sequence b1,b2,...,bn in such a manner that F(a1,a2,...,an) equals to F(b1,b2,...,bn) . Among all the possible sequences consisting of only positive integers, Peter wants the lexicographically smallest one.
The sequence a1,a2,...,an is lexicographically smaller than sequence b1,b2,...,bn , if there is such number i from 1 to n , that ak=bk for 1≤k<i and ai<bi .
Peter would like to find another sequence b1,b2,...,bn in such a manner that F(a1,a2,...,an) equals to F(b1,b2,...,bn) . Among all the possible sequences consisting of only positive integers, Peter wants the lexicographically smallest one.
The sequence a1,a2,...,an is lexicographically smaller than sequence b1,b2,...,bn , if there is such number i from 1 to n , that ak=bk for 1≤k<i and ai<bi .
Input
There are multiple test cases. The first line of input contains an integer
T
, indicating the number of test cases. For each test case:
The first contains an integer n (1≤n≤100000) -- the length of the sequence. The second line contains n integers a1,a2,...,an (1≤ai≤109) .
The first contains an integer n (1≤n≤100000) -- the length of the sequence. The second line contains n integers a1,a2,...,an (1≤ai≤109) .
Output
For each test case, output
n
integers
b1,b2,...,bn
(1≤bi≤109)
denoting the lexicographically smallest sequence.
Sample Input
3
1
10
5
5 4 3 2 1
3
1 3 5
Sample Output
1
1 1 1 1 1
1 2 3
3
1
10
5
5 4 3 2 1
3
1 3 5
Sample Output
1
1 1 1 1 1
1 2 3
Source
中文题意:
思路:
1、显然,其实令bi为最小字典序,其实就是在求f1,f2,f3,......................
2、又显然,n^2会超时,那么我们用nlogn的方式来解决。
Ac代码:
#include <iostream>
#include<stdio.h>
using namespace std;
int a[1000000],b[1000000],c[1000000];
int find(int *a,int len,int n)//若返回值为x,则a[x]>=n>a[x-1]
{
int left=0,right=len,mid=(left+right)/2;
while(left<=right)
{
if(n>a[mid]) left=mid+1;
else if(n<a[mid]) right=mid-1;
else return mid;
mid=(left+right)/2;
}
return left;
}
void fill(int *a,int n)
{
for(int i=0;i<=n;i++)
a[i]=1000000010;
}
int main()
{
int max,i,j,n;
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
fill(c,n+1);
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
c[0]=-1;// …………………………………1
c[1]=a[0];// …………………………2
b[0]=1;// …………………………………3
for(i=1;i<n;i++)// ………………4
{
j=find(c,n+1,a[i]);// …………………5
c[j]=a[i];// ………………………………6
b[i]=j;//……………………………………7
}
for(int i=0;i<n-1;i++)
{
printf("%d ",b[i]);
}
printf("%d\n",b[n-1]);
}
}