传送门:点击打开链接
题意:有许多人带有权值的礼物来拜访公主,公主会在第ti个人到的时候把门打开瞬间,放ki个人进来,其中进来的顺序是权值最大的先进,如果权值一样大就先来的先进。当人全部到齐后会再次开门让所有人都进来。
思路:先将开门的时间读入然后排序,然后模拟将n个人都插入到优先对列中,然后离线维护答案,最后输出即可
#include<map>
#include<set>
#include<cmath>
#include<stack>
#include<queue>
#include<cstdio>
#include<cctype>
#include<string>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
#define fuck printf("fuck")
#define FIN freopen("input.txt","r",stdin)
#define FOUT freopen("output.txt","w+",stdout)
using namespace std;
typedef long long LL;
const int MX = 150000 + 5;
string name[MX];
struct Data {
int value, id;
bool operator<(const Data &b)const {
if(b.value == value) return id > b.id;
return value < b.value;
}
} A[MX];
struct Que {
int Begin, num;
bool operator<(const Que &b)const {
return Begin < b.Begin;
}
} Q[MX];
int ans[MX];
char word[300];
int main() {
int T, n, m, q; //FIN;
scanf("%d", &T);
while(T--) {
scanf("%d%d%d", &n, &m, &q);
for(int i = 1; i <= n; i++) {
scanf("%s%d", word, &A[i].value);
name[i] = string(word);
A[i].id = i;
}
for(int i = 1; i <= m; i++) {
scanf("%d%d", &Q[i].Begin, &Q[i].num);
}
sort(Q + 1, Q + 1 + m);
int tot = 0, cur = 1;
priority_queue<Data>work;
for(int i = 1; i <= n; i++) {
while(cur <= m && i == Q[cur].Begin + 1) {
int size = min((int)work.size(), Q[cur].num);
for(int j = 1; j <= size; j++) {
Data f = work.top();
work.pop();
ans[++tot] = f.id;
}
cur++;
}
work.push(A[i]);
}
while(!work.empty()) {
Data f = work.top();
work.pop();
ans[++tot] = f.id;
}
for(int i = 1; i <= q; i++) {
int id;
scanf("%d", &id);
printf("%s%c", name[ans[id]].c_str(), i == q ? '\n' : ' ');
}
}
return 0;
}