题意:
Alisha过生日,有k个朋友先后到来,且携带价值vi的礼物。Alisha的房间很小,所以她打算开m次门,分别在ti个朋友到达之后,让携带礼物价值前pi高的朋友按礼物价值依次进入房间,如果pi大于在门口等待的人数,则让他们全部进入房间,如果两个人的礼物价值相等,则让先来的人先进。开m次门之后,如果还有没进入过房间的朋友,则让他们按礼物价值依次全部进入房间。最后q个询问,每个询问一个ni,让你求第ni个进入房间的朋友的名字。
思路:
我是用了好几个STL进行的模拟。对于q次询问,我把不同的ni作为键存入map,然后ni所对应的值是第几次询问即i,如果ni在之前出现过,则我把map中ni对应的值即上一次的下标取负存下,在最后输出的时候处理一下再输出即可,这样就实现了logn的取出之后模拟时需要记录的次序,然后对m次开门排个序用set进行模拟就好了。
代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 15e4+1;
struct node
{
int id, val;
bool operator<(const node k)const
{
if(val == k.val) return id < k.id;
return val > k.val;
}
};
char s[maxn][201];
int v[maxn];
set<node> st;
set<node>::iterator it;
pair<int, int> pr[maxn];
int ned[105];
map<int, int> mp;
map<int, int>::iterator iter;
vector<node> vt;
int T, K, M, Q;
int cmp(pair<int, int> pr1, pair<int, int> pr2)
{return pr1.first < pr2.first;}
int main()
{
//freopen("in.txt", "r", stdin);
int x, pre, id;
for(scanf("%d", &T); T--;)
{
scanf("%d %d %d", &K, &M, &Q);
for(int i = 1; i <= K; ++i)
{
scanf("%s", s[i]);
scanf("%d", &v[i]);
}
for(int i = 1; i <= M; ++i)
scanf("%d %d", &pr[i].first, &pr[i].second);
mp.clear();
for(int i = 1; i <= Q; ++i)
{
scanf("%d", &x);
if(mp.find(x) != mp.end()) ned[i] = -mp[x];
else mp[x] = i;
}
sort(pr+1, pr+M+1, cmp);
pre = 1, id = 1;
st.clear();
for(int i = 1; i <= M; ++i)
{
iter = mp.begin();
int t = iter->first;
if(pr[i].first-pre+1+st.size() <= pr[i].second && id+
pr[i].first-pre+1+st.size()-1 < t)
{
st.clear();
id += pr[i].first-pre+1+st.size();
pre = pr[i].first+1;
continue;
}
for(int j = pre; j <= pr[i].first; ++j)
st.insert((node){j, v[j]});
vt.clear();
for(it = st.begin(); it != st.end() && vt.size() < pr[i].second; ++it)
vt.push_back(*it);
while(id+vt.size()-1 >= t)
{
ned[mp[t]] = vt[t-id].id;
mp.erase(t);
if(mp.empty()) break;
iter = mp.begin();
t = iter->first;
}
if(mp.empty()) break;
for(int j = 0; j < vt.size(); ++j)
st.erase(vt[j]);
id += vt.size();
pre = pr[i].first+1;
}
if(!mp.empty())
{
for(int i = pre; i <= K; ++i)
st.insert((node){i, v[i]});
int t = 0;
for(it = st.begin(); it != st.end() && !mp.empty(); ++it, ++t)
{
if(mp.find(id+t) != mp.end())
{
ned[mp[id+t]] = it->id;
mp.erase(id+t);
}
}
}
for(int i = 1; i <= Q; ++i)
{
if(ned[i] < 0) printf("%s", s[ned[-ned[i]]]);
else printf("%s", s[ned[i]]);
printf("%c", i==Q?'\n':' ');
}
}
return 0;
}
继续加油~