参照博客
注意点:
技巧 :
#include
using namespace std;
typedef long long ll;
const long long NUM = (long long)(1e9);
/*
注意点
1. #define NUM 1000000000 会溢出
2. res[t]不用排序
*/
/*
技巧
1. id用哈希函数 type*10^9 + comm 方便映射
2. map存储对应id在set中插入的位置 关联式容器插入删除元素不影响其它结点的迭代器
3. set.insert()的返回值是pair::iterator, bool>
*/
struct Node{
ll id;
int score;
Node(ll id, int score):id(id), score(score){};
bool operator < (const Node& a)const{//重载<,自定义set中的排序,分数大的排前,socre相同的,id小的排前
if(score == a.score) {
return id < a.id;
}
else{
return score > a.score;
}
}
};
unordered_map<ll, set<Node>::iterator>um;//存储set中元素的iterator
set<Node>comms;
int cnt[55];
int main(){
//freopen("E:\\a.txt", "r", stdin);
int m, n, id, score, op;
int num, type, comm, sum;
scanf("%d%d", &m, &n);
for(int i = 0; i < n; ++i){
scanf("%d%d", &id, &score);
for(int j = 0; j < m; ++j){
ll no = j * NUM + id;
um[no] = comms.insert(Node(no, score)).first;//用map存储元素在set中的位置,方便删除
}
}
scanf("%d", &op);
for(int i = 0; i < op; ++i){
scanf("%d", &num);
if(num == 1){//插入
scanf("%d%d%d", &type, &comm, &score);
ll no = type * NUM + comm;
um[no] = comms.insert(Node(no, score)).first;//注意将新元素的iter添加到map
}
else if(num == 2){
scanf("%d%d", &type, &comm);
ll no = type * NUM + comm;
comms.erase(um[no]);//删除set中对应的id
um.erase(no);//删除map中的id
}
else if(num == 3){
scanf("%d", &sum);
for(int j = 0; j < m; ++j){
scanf("%d", &cnt[j]);
}
vector<vector<int> >res(55);
for(auto& it:comms){//注意对cnt数组和sum计数
type = it.id / NUM;
comm = it.id % NUM;
if(cnt[type]){
res[type].push_back(comm);
--cnt[type];
--sum;
if(sum == 0){
break;
}
}
}
for(int j = 0; j < m; ++j){
if(res[j].size() == 0){
printf("-1\n");
}
else{
//sort(res[j].begin(), res[j].end());
for(int t = 0; t < res[j].size(); ++t){//输出
printf("%s%d", t == 0?"":" ", res[j][t]);
}
printf("\n");
}
}
}
}
return 0;
}
github地址