题目链接:http://oj.daimayuan.top/problem/465
题意:给定n个整数,对于每个数你需要输出前面没有出现过的且大于等于它本身的最小正整数。
样例输入:
6
2 3 4 1 1 1
样例输出
2 3 4 1 5 6
代码:
set<pair<int,int> >
#include<bits/stdc++.h>
using namespace std;
set<pair<int,int> >s;
//用set维护一些可行区间
void myinsert(int l,int r){
if(l>r) return;
s.insert({r,l});
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int n;
cin>>n;
s.insert({2e9, 1});
for(int i=0;i<n;i++){
int x;
cin>>x;
auto it = s.lower_bound({x,0});//找到大于x的最近的一个可行区间
int l = it->second, r = it->first;//可行区间的端点
s.erase(it);
if(x>l){//x在可行区间中间,不包括左端点
cout<<x<<" ";
myinsert(l,x-1);
myinsert(x+1,r);
}
else{//x在可行区间左边,包括左端点
cout<<l<<" ";
myinsert(l+1,r);
}
}
return 0;
}
并查集
用并查集来维护,x能达到的下一个位置
#include<bits/stdc++.h>
using namespace std;
const int N = 5e5+5;
unordered_map<int,int>f;
//用并查集来维护一个数x能放的位置
long long find(int x){
return f.count(x)==0 ? x : f[x] = find(f[x]);
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
int n;
cin>>n;
for(int i=0;i<n;i++){
int x;
cin>>x;
//把这个数放到这个位置后,找到x下一次能到达的位置
int fx = find(x);
cout<<fx<<" ";
f[fx] = fx + 1;
}
return 0;
}