STL/set Codeforces Round #710 (Div. 3) E题
题意:
给一数组q,求原数组a,给定的数组的第i位表示原数组1到i的最大值。
输出可能的原数组的最小字典序和最大字典序
解析:
如果q[i] = q[i-1],代表新的数字不大于所有前面出现过的数字
如果q[i] > q[i-1],代表新的数字更新了最大值,a[i] = q[i]
如果q[i] < q[i-1] ? 这不存在,因为q[i]代表从1到 i 的最大值
策略- 先将所有确定的a[i]都定好,将未确定的数加入set里,
从前往后遍历,
如果是要生成最小的字典序,则每次取set.begin()
如果要生成最大的字典序,利用set.lower_bound(x)找到大于等于当前的数的位置,然后–,往前退一步,就是小于当前数的最大值。
int t,n,m;
int a[N];
void cul(vector<int> &q, bool flag){
set<int> se;
for(int i=1;i<=q.size();i++) se.insert(i);
for(int i=0;i<q.size();i++)
if(q[i] != -1) se.erase(q[i]);
int last = -1;
for(int i=0;i<q.size();i++){
set<int> :: iterator it;
if(q[i] == -1){
if(flag){
it = se.begin();
}else{
it = --se.lower_bound(last);
}
q[i] = *it;
se.erase(*it);
}else{
last = q[i];
}
}
}
int main(){
scanf("%d",&t);
while(t--){
scanf("%d",&n);
vector<int> res1(n,-1),res2(n,-1);
int last = -1;
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
if(a[i] != last){
res1[i] = a[i];
res2[i] = a[i];
last = a[i];
}
}
cul(res1,true);
cul(res2,false);
for(int t : res1) printf("%d ",t);
puts("");
for(int t : res2) printf("%d ",t);
puts("");
}
return 0;
}