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
a
1
,a
2
,...,a
n![]()
and he define a function on the sequence --
F(a
1
,a
2
,...,a
n
)=(f
1
,f
2
,...,f
n
)
, where
f
i![]()
is the length of the longest increasing subsequence ending with
a
i![]()
.
Peter would like to find another sequence b
1
,b
2
,...,b
n![]()
in such a manner that
F(a
1
,a
2
,...,a
n
)
equals to
F(b
1
,b
2
,...,b
n
)
. Among all the possible sequences consisting of only positive integers, Peter wants the lexicographically smallest one.
The sequence a
1
,a
2
,...,a
n![]()
is lexicographically smaller than sequence
b
1
,b
2
,...,b
n![]()
, if there is such number
i
from
1
to
n
, that
a
k
=b
k![]()
for
1≤k<i
and
a
i
<b
i![]()
.
Peter would like to find another sequence b
The sequence a
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
a
1
,a
2
,...,a
n![]()
(1≤a
i
≤10
9
)
.
The first contains an integer n
Output
For each test case, output
n
integers
b
1
,b
2
,...,b
n![]()
(1≤b
i
≤10
9
)
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]);
}
}