UTR#2 T1

时间:2023-03-08 15:47:22
UTR#2 T1

题意:给定一个n,以下n个数(假定为fi),要求构造一个n个数的序列,使得这个序列每一个位置的最大上升子序列的长度等于对应的fi。

其实这道题是个很简单的题,之前7月也在BC上做到过,为什么要写呢,因为思维过程还是挺好的。

考虑我们要构造这么一个序列,每个位置要满足什么条件呢?首先,对于一个位置,这个位置之前的那些位置,如果它们的fi大于等于这个位置上的fi,那么我们给这个位置放的数一定要小于前面那些位置上的数,而对于小于这个位置的fi的那些位置,我们的值又要大于它们的值,也就是说安排后我们要保证fi大的位置分配给它的数一定要大。那么对于两个fi相同的位置,怎么办呢?一定是位置靠后的那个分配的小。为什么呢,很显然,如果大了的话,就可以使最大上升子序列的长度加1了。

所以这道题做法就出来了:以fi为第一关键字升序,下标为第二关键字降序,排一道序,然后对应地填上1-n这些数就好了。

 #include<bits/stdc++.h>
using namespace std;
#define N 100005
inline int read(){
int x=,f=; char a=getchar();
while(a<'' || a>'') {if(a=='-') f=-; a=getchar();}
while(a>='' && a<='') x=x*+a-'',a=getchar();
return x*f;
}
struct data{
int num,pos;
bool operator < (const data& w)const{
if(num==w.num) return pos>w.pos;
return num<w.num;
}
}a[N];
int n,ans[N];
int main(){
n=read();
for(int i=;i<=n;i++)
a[i].num=read(),a[i].pos=i;
sort(a+,a++n);
for(int i=;i<=n;i++)
ans[a[i].pos]=i;
for(int i=;i<=n;i++)
printf("%d ",ans[i]);
return ;
}