传送门:点击打开链接
题意:有许多人带有权值的礼物来拜访公主,公主会在第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;
}