一开始写想用Treap,但是没有想好。。结果没用,用的是list维护工作名单,两个map来维护从字符串到价值的映射和价值到字符串的映射,果断的超时。
后来请教了学长,用了两个set,一个set维护工作名单,另外一个set维护非工作名单,然后一个map是字符串到价值的映射,这样写方便很多呀!
Tips:我这里的价值是一个pair,first是动机的等级,second是时间,这样共同作为价值的话就很好比较了。
写的时候分情况讨论一下喽,加人的时候特判一下工作名单是不是空,以及是不是工作名单会多一个人之类的。
我这里的wl代表work list,工作名单,nwl代表 not work list,非工作名单
#include<iostream>
#include<string>
#include<set>
#include<cmath>
#include<algorithm>
#include<map>
using namespace std;
struct Node{
string name;
int val,time;
Node(const string& n="",const int v=0,const int t=0):name(n),val(v),time(t){};
bool operator<(const Node& a)const{
return val>a.val||val==a.val&&time>a.time;
}
}te;
set<Node> wl,nwl;
map<string,pair<int,int> > ma;
int n,m,lim,tem;
char order;
string str;
int main(){
ios_base::sync_with_stdio(false);
while(cin>>n){
for(int i=1;i<=n;++i)
cin>>te.name>>te.val,++te.time,nwl.insert(te),ma[te.name]=make_pair(te.val,te.time);
lim=floor(n*0.2);
for(int i=1;i<=lim;++i)
wl.insert(*nwl.begin()),nwl.erase(nwl.begin());
cin>>m;
lim=n+m;
for(int i=n+1;i<=lim;++i){
cin>>order>>str;
if(order=='+'){
cin>>tem;
ma[str]=make_pair(tem,i);
if(floor((n+1)*0.2)-floor(n*0.2)<1E-6){
++n;
if(wl.empty()){
nwl.insert(Node(str,tem,i));
cout<<str<<" is not working now.\n";
}
else{
if(tem>=(--wl.end())->val){
cout<<str<<" is working hard now.\n"<<(--wl.end())->name<<" is not working now.\n";
nwl.insert(*(--wl.end()));
wl.erase(--wl.end());
wl.insert(Node(str,tem,i));
}
else{
cout<<str<<" is not working now.\n";
nwl.insert(Node(str,tem,i));
}
}
}
else{
++n;
if(wl.empty()){
nwl.insert(Node(str,tem,i));
if(nwl.begin()->name==str)
cout<<str<<" is working hard now.\n";
else
cout<<str<<" is not working now.\n"<<nwl.begin()->name<<" is working hard now.\n";
wl.insert(*nwl.begin());
nwl.erase(nwl.begin());
}
else{
if(tem>=(--wl.end())->val){
cout<<str<<" is working hard now.\n";
wl.insert(Node(str,tem,i));
}
else{
nwl.insert(Node(str,tem,i));
if(nwl.begin()->name==str)
cout<<str<<" is working hard now.\n";
else
cout<<str<<" is not working now.\n"<<nwl.begin()->name<<" is working hard now.\n";
wl.insert(*nwl.begin());
nwl.erase(nwl.begin());
}
}
}
}
else{
if(floor(n*0.2)-floor((n-1)*0.2)<1E-6){
--n;
te=Node(str,ma[str].first,ma[str].second);
if(wl.end()==wl.find(te)){
ma.erase(str);
nwl.erase(te);
}
else{
ma.erase(str);
wl.erase(te);
cout<<nwl.begin()->name<<" is working hard now.\n";
wl.insert(*nwl.begin());
nwl.erase(nwl.begin());
}
}
else{
--n;
te=Node(str,ma[str].first,ma[str].second);
set<Node>::iterator it = wl.find(te);
if(it==wl.end()){
nwl.erase(te);
cout<<((--wl.end())->name)<<" is not working now.\n";
nwl.insert(*(--wl.end()));
wl.erase(--wl.end());
}
else
wl.erase(it);
}
}
}
ma.clear();
wl.clear();
nwl.clear();
}
return 0;
}