【堆+模擬】[CodeForces-235E]printer
題目大意
我們考慮一個有這樣功能的網路印表機: 他從時刻 0 開始工作, 每一秒鐘他列印一
頁紙。 某些時刻他會收到一些列印任務。 我們知道印表機會收到 n 個任務, 我們將它們
分別編號為連續的整數 1~n, 並且第 i 個任務用三個引數描述: t_i 表示接到的時間, s_i
表示任務要求你列印多少張, 以及 p_i 表示任務的一個優先順序。 所有任務的優先順序互不
相同。
當一個印表機收到一個任務時, 任務會進入一個佇列並留下直到完成了這個任務為
止。 在任務佇列非空時, 每個時刻, 印表機會選擇佇列裡優先順序最高的一個任務, 列印
一頁。 你可以想象任務進入佇列是瞬間的事情, 所以他可以在收到某個任務的時刻去執
行這個任務。
你會得到除了某個任務以外所有任務的資訊: 你不知道某個任務的優先順序是多少。
然而, 我們還額外的知道這個任務他完成時的時刻。 我們給你這些資訊, 請求出這個未
知的優先順序並對每個任務輸出它完成時的時刻。
分析
由於印表機每個時刻是列印優先順序最高的那一個任務,所以可以很容易地想到用一個堆來維護。
模擬列印過程
將任務根據時間排序,然後時間軸遞增.
當前時間點為
找優先順序
當可以加入任務x的時候,將堆中的所有任務取出來,並且找到將會在
程式碼
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define MAXN 50000
using namespace std;
typedef pair<int,int>pii;
typedef pair<int,pii>pip;
priority_queue<pip>q;
pip tmp[MAXN+10 ];
template<class T>
void Read(T &x){
char c;
bool f=0;
while(c=getchar(),c!=EOF){
if(c=='-')
f=1;
if(c>='0'&&c<='9'){
x=c-'0';
while(c=getchar(),c>='0'&&c<='9')
x=x*10+c-'0';
ungetc(c,stdin);
if(f)
x=-x;
return;
}
}
}
int n,cnt,x,pset[MAXN+10];
long long T,ans[MAXN+10];
struct task{
int t,s,p,pos;
inline task(){
}
inline task(int t,int s,int p,int pos):t(t),s(s),p(p),pos(pos){
}
bool operator<(const task&a)const{
return t<a.t;
}
}a[MAXN+10];
void read(){
Read(n);
int i,t,s,p;
for(i=1;i<=n;i++){
Read(t),Read(s),Read(p);
a[i]=task(t,s,p,i);
pset[i]=p;
}
Read(T);
}
long long check(int p){
int i;
long long ret=0;
for(i=1;i<=cnt;i++)
if(tmp[i].first>=p)
ret+=tmp[i].second.second;
for(i=x+1;a[i].t<T&&i<=n;i++)
if(a[i].p>=p)
ret+=a[i].s;
return ret;
}
int Divide_Conqure(int l,int r,int t){
int mid;
while(l<r){
mid=(l+r)>>1;
if(check(mid)<=T-t-a[x].s)
r=mid;
else
l=mid+1;
}
return l;
}
void solve(){
sort(a+1,a+n+1);
sort(pset+1,pset+n+1);
int i;
long long t;
pip u;
i=1,t=0;
while(!q.empty()||i<=n){
if(q.empty()||t==a[i].t){
t=a[i].t;
if(a[i].p==-1)
break;
q.push(pip(a[i].p,pii(a[i].pos,a[i].s)));
i++;
}
else{
if(i>n||t+q.top().second.second<=a[i].t){
u=q.top(),q.pop();
t+=u.second.second;
ans[u.second.first]=t;
}
else{
u=q.top(),q.pop();
u.second.second-=a[i].t-t;
q.push(u);
t=a[i].t;
}
}
}
x=i;
while(!q.empty()){
tmp[++cnt]=q.top();
q.pop();
}
a[i].p=Divide_Conqure(1,1000000000,t);
int tt=lower_bound(pset+1,pset+n+1,a[i].p)-pset;
while(a[i].p==pset[tt]&&tt<=n)
a[i].p++,tt++;
for(i=1;i<=cnt;i++)
q.push(tmp[i]);
i=x;
printf("%d\n",a[x].p);
while(!q.empty()||i<=n){
if(q.empty()||t==a[i].t){
t=a[i].t;
q.push(pip(a[i].p,pii(a[i].pos,a[i].s)));
i++;
}
else{
if(i>n||t+q.top().second.second<=a[i].t){
u=q.top(),q.pop();
t+=u.second.second;
ans[u.second.first]=t;
}
else{
u=q.top(),q.pop();
u.second.second-=a[i].t-t;
q.push(u);
t=a[i].t;
}
}
}
}
void print(){
int i;
for(i=1;i<n;i++)
printf("%I64d ",ans[i]);
printf("%I64d\n",ans[n]);
}
int main()
{
read();
solve();
print();
}