Bellovin
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 1076 Accepted Submission(s): 485
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
Source
Recommend
思路:求到各个元素的最长上升子序列
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
const int N = 1e5+5;
int a[N],b[N],dp[N];
int find(int l,int r,int x) {
while(l<=r) {
int mid=l+r>>1;
if(dp[mid]>x) r=mid-1;
else if(dp[mid]<x) l=mid+1;
else {
l=mid;
break;
}
}
return l;
}
int main() {
int T;
scanf("%d",&T);
while(T--) {
int n;
scanf("%d",&n);
for(int i=0; i<n; i++) {
scanf("%d",&a[i]);
}
int len=0;
dp[0]=-1;
for(int i=0; i<n; i++) {
if(a[i]>dp[len]) {
dp[++len]=a[i];
b[i]=len;
} else {
int j=find(1,len,a[i]);
b[i]=j;
dp[j]=a[i];
}
}
for(int i=0; i<n; i++) {
if(!i)
printf("%d",b[i]);
else
printf(" %d",b[i]);
}
printf("\n");
}
return 0;
}
题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=5748