传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3117
认认真真模拟就行,时间用优先队列,内存用链表,注意各种细节。
PS:代码好丑啊……
Code:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cctype>
#include<queue>
#include<set>
#include<vector>
#include<list>
using namespace std;
const int maxn=1e4+10;
int getint(){
int res=0;
char ch,ok=0;
while(1){
ch=getchar();
if(isdigit(ch)){
res*=10;res+=ch-'0';ok=1;
}else if(ok)break;
}return res;
}
struct task{
int t,m,p,f,ind;
task(int _t=0,int _m=0,int _p=0,int _f=0,int _ind=0){
t=_t,m=_m,p=_p,f=_f,ind=_ind;
}
};
task tasks[maxn<<1];
int n,ans1,ans2,tot;
struct cmp{
bool operator()(int a,int b){return tasks[a].t>tasks[b].t||(tasks[a].t==tasks[b].t&&tasks[a].f>tasks[b].f);}
};
priority_queue<int,vector<int>,cmp>que;
queue<int>q;
struct block{
int l,r,ind,used;
block(int _l=0,int _r=0,int _ind=0,int _used=0){
l=_l,r=_r,ind=_ind,used=_used;
}
};
list<block>List;
void deb(){
for(list<block>::iterator it=List.begin();it!=List.end();it++)
printf("l:%d r:%d ind:%d\t",it->l,it->r,it->ind);cout<<endl;
}
bool insert(int x){
for(list<block>::iterator it=List.begin();it!=List.end();it++){
if(!it->used&&(it->r-it->l+1>=tasks[x].m)){
list<block>::iterator i=List.insert(++it,block(it->l,it->l+tasks[x].m-1,x,1));
it=--i;i++;
if(it->l+tasks[x].m-1<it->r)
List.insert(++i,block(it->l+tasks[x].m,it->r,0,0));
List.erase(it);
return true;
}
}
return false;
}
void erase(int x){
if(List.size()==1){List.begin()->ind=0,List.begin()->used=0;return;}
for(list<block>::iterator it=List.begin();it!=List.end();it++){
if(it->ind==x){
if(it==List.begin()){
list<block>::iterator nxt=it;nxt++;
if(!nxt->used){
List.insert(++nxt,block(1,nxt->r,0,0));
List.pop_front();List.pop_front();
}else it->ind=0,it->used=0;
}else
if(it==--List.end()){
list<block>::iterator pre=it;pre--;
if(!pre->used){
List.insert(pre,block(pre->l,n,0,0));
List.pop_back();List.pop_back();
}else it->ind=0,it->used=0;
}else{
list<block>::iterator pre=it;pre--;
list<block>::iterator nxt=it;nxt++;
if(!pre->used&&!nxt->used){
list<block>::iterator i=List.insert(pre,block(pre->l,nxt->r,0,0));
i++;
i=List.erase(i);i=List.erase(i);i=List.erase(i);
}else
if(!pre->used){
list<block>::iterator i=List.insert(pre,block(pre->l,it->r,0,0));
i++;
i=List.erase(i);i=List.erase(i);
}else
if(!nxt->used){
// cout<<it->l<<" "<<nxt->r<<endl;
list<block>::iterator i=List.insert(it,block(it->l,nxt->r,0,0));
i++;
i=List.erase(i);i=List.erase(i);
}else it->ind=0,it->used=0;
}break;
}
}
}
int main(){
n=getint();List.push_back(block(1,n,0,0));
while(++tot){
tasks[tot].t=getint(),tasks[tot].m=getint(),tasks[tot].p=getint();
if(tasks[tot].t==0&&tasks[tot].m==0){tot--;break;}
tasks[tot].f=1;tasks[tot].ind=tot;
que.push(tot);
}
while(!que.empty()){
int top=que.top(),tt=top;
ans1=max(ans1,tasks[top].t);
// cout<<tasks[top].t<<endl;
// deb();
if(tasks[top].f==1){
// deb();
que.pop();
if(insert(top)){
++tot;
tasks[tot]=tasks[top];
tasks[tot].t=tasks[top].t+tasks[tot].p;ans1=max(ans1,tasks[tot].t);
tasks[tot].f=-1;
que.push(tot);
}else{
q.push(top);
ans2++;
}
// deb();
}else{
bool jj=0;
// deb();
while(que.size()>1){
top=que.top();que.pop();
int tp=que.top();
if(tasks[top].f==-1){
erase(tasks[top].ind);}
else{
que.push(tp);
break;
}
if(tasks[top].f==-1&&tasks[tp].f==-1&&tasks[tp].t==tasks[top].t){
// que.pop();
}else {
jj=1;break;
}
}if(!que.empty()&&!jj){
top=que.top();
if(tasks[top].f==-1){
erase(tasks[top].ind),que.pop();}
}
if(q.size())
while(insert(q.front())){
++tot;
tasks[tot]=tasks[q.front()];
tasks[tot].t=tasks[tt].t+tasks[tot].p;ans1=max(ans1,tasks[tot].t);
tasks[tot].f=-1;
que.push(tot);
q.pop();if(q.empty())break;
}
}
// deb();
}
cout<<ans1<<endl;
cout<<ans2<<endl;
return 0;
}