对于排列 (p),它的单调栈 (f) 定义为,(f_i) 是以 (p_i) 结尾的最长上升子序列的长度
先给定 (f) 中一些位置的值,求字典序最小的 (p) 使得它满足这些值
Solution
显然 (f[1]=1),考虑所有满足 (f[x]=1) 的位置 (b_1,dots,b_k),一定有 (p_{b_1}>p_{b_2}>dots >p_{b_k})
由于 (b_1=1),我们要最小化 (p_1),所以填入 (p_{b_i}=k-i+1)
然后考虑所有 (f[x]=2) 的数,同理操作(注意第一个数仍然为最小),填入值加一个偏移即可
最后,对于 (f) 值没有给出的那些数,从左到右从小到大填入即可
#include <bits/stdc++.h>
using namespace std;
const int N = 105;
int n,t,s,f[N],p[N];
signed main() {
ios::sync_with_stdio(false);
cin>>t;
while(t--) {
cin>>n;
for(int i=1;i<=n;i++) cin>>f[i];
int sum=0;
memset(p,0,sizeof p);
for(int i=1;i<=n;i++) {
stack<int> v;
for(int j=1;j<=n;j++) if(p[j]==0) {
f[j]=i;break;
}
for(int j=1;j<=n;j++) if(f[j]==i) v.push(j);
while(v.size()) p[v.top()]=++sum, v.pop();
}
for(int i=1;i<=n;i++) if(p[i]==0) p[i]=++sum;
for(int i=1;i<=n;i++) cout<<p[i]<<(n==i?"":" ");
cout<<endl;
}
}