二分加并查集
小缘开了一家公司,生意很好,每天都会收到很多订单,自动交易系统会自动给这些订单生成没有重复的订单编号。但是有一天,系统出现了未知的错误,导致当天的订单编号可能有重复的,这可把小缘急坏了。你可以帮助小缘按照规则给这些订单重新编号吗?
按照时间先后顺序给出 NN 个正整数作为原订单编号,你需要按照规则依次赋予这些订单新的编号,对于任意一个订单,要找到大于等于其原订单编号且未被使用过的(没有被之前的订单作为新的订单编号)的最小整数,作为它的新订单编号。
例如: 原订单编号依次为1 2 3 1,则新订单编号应该为1 2 3 4 (前3个订单的原订单编号都没有使用过,所以用其原订单编号即可,对于第四个订单,原订单编号为1,而1, 2, 3都已经被使用过,所以新订单编号为4)。
输入格式
第一行输入一个整数 NN (1≤N≤5×105)(1≤N≤5×105)。
第二行输入 NN 个数 aiai (1≤ai≤109)(1≤ai≤109) 作为原订单编号。
输出格式
输出一行,包含 NN 个整数为新的订单编号。
样例输入1
6
2 3 4 1 1 1
样例输出1
2 3 4 1 5 6
样例输入2
3
1000000000 1000000000 1000000000
样例输出2
1000000000 1000000001 1000000002
样例输入3
6
4 5 1 2 1 1
样例输出3
4 5 1 2 3 6
代码----------
#include<bits/stdc++.h>
using namespace std;
set<pair<int ,int >>s;
void insert(int l, int r)
{
if(l > r) return;
s.insert({r, l});
}
int main()
{
int n,x;
scanf("%d",&n);
s.insert({2e9, 1});
for(int i=0;i<n;i++)
{
scanf("%d",&x);
auto pos = s.lower_bound({x, 0});
if(pos->second <= x)
{
printf("%d ",x);
insert(pos->second, x - 1);
insert(x + 1,pos->first);
s.erase(pos);
}
else
{
//cout << pos -> second << ' ';
printf("%d ",pos->second);
insert(pos->second + 1, pos->first);
s.erase(pos);
}
}
}