代码源每日一题DIV2 #106 订单编号
- 思路
- 使用set维护未使用编号,即set里面的所有区间中的每个编号都是未被使用过的,每次根据编号的情况进行打印新编号以及维护区间
- 学到的东西
- 用set维护区间的思想
- 将点问题包含入区间中进行求解
- 编码技巧:set里面可以装pair,且pair中进行lower_bound的效果为
-
lower_bound() returns an iterator pointing to the first element in the range [first, last) which has a value greater than or equals to the given value “val”. But in set of Pairs lower_bound() for pair(x, y) will return an iterator pointing to the position of pair whose the first value is greater than or equals x.
AC代码
const int maxn = 5e5 + 5;
int a[maxn];
set<pair<int, int>> st; // 维护未被使用的编号,set里面的每个区间的所有编号都是未被使用的
void insert(int l,int r){
if (l>r) return;
st.insert({r,l});
}
void solve() {
int n;cin>>n;
for (int i = 1; i <= n; ++i) {
cin>>a[i];
}
st.insert(make_pair(2e9,1));
for (int i = 1; i <=n ; ++i) {
auto it = st.upper_bound({a[i],0});
int l=it->second,r=it->first;
if (a[i]>l) {
cout<<a[i]<<" ";
st.erase(it);
insert(l,a[i]-1);
insert(a[i]+1,r);
} else{
cout<<l<<" ";
st.erase(it);
insert(l+1,r);
}
}
}
signed main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
solve();
}
UPDATE:用unorder_map维护并查集的方法
unordered_map<int,int> m;
int find(int x){
if (!m[x]) return x;
return m[x]= find(m[x]);
}
void solve() {
int n;cin>>n;
for (int i = 1; i <=n ; ++i) {
int x;cin>>x;
int t = find(x);
cout<<t<<" ";
m[t]=t+1;
}
}
signed main() {
std::ios::sync_with_stdio(false);
std::cin.tie(0);
std::cout.tie(0);
solve();
}