题意:
有一个电梯,有
n
个人。
第
每一个时刻,设
pup
为想要去楼上的在电梯中的人数与在楼上等待的人数之和,
pdown
为想要去楼下的在电梯中的人数与在楼下等待的人数之和,若
pup≥pdown
则向上走一层,否则向下走一层。输出每个人到达目的地的时刻。
4个set维护四种人,关键时刻只有
O(n)
个,所以暴力模拟就好了。
时间复杂度
O(nlogn)
。
#include <bits/stdc++.h>
#define gc getchar()
#define ll long long
#define N 100009
#define inf 0x3f3f3f3f
using namespace std;
int n,m;
ll Ans[N];
int read()
{
int x=1;
char ch;
while (ch=gc,ch<'0'||ch>'9') if (ch=='-') x=-1;
int s=ch-'0';
while (ch=gc,ch>='0'&&ch<='9') s=s*10+ch-'0';
return x*s;
}
struct passenger
{
int t,s,f,pos;
void scan(int i)
{
t=read(),s=read(),f=read(),pos=i;
}
bool operator <(const passenger &rhs) const
{
return t<rhs.t;
}
}p[N],q[N];
struct node
{
int id,pos;
node(int id=0,int pos=0):id(id),pos(pos){}
bool operator <(const node &rhs) const
{
return pos<rhs.pos;
}
bool operator >(const node &rhs) const
{
return pos>rhs.pos;
}
};
multiset<node,less<node> > to_up,from_up;
multiset<node,greater<node> > to_down,from_down;
int pos=1,finish=0,id=1;
ll t=1;
void add_from()
{
while (p[id].t==t)
{
if (pos==p[id].s)
{
if (p[id].f>pos) to_up.insert(node(p[id].pos,p[id].f));
else to_down.insert(node(p[id].pos,p[id].f));
}
else
{
if (p[id].s>pos) from_up.insert(node(p[id].pos,p[id].s));
else from_down.insert(node(p[id].pos,p[id].s));
}
id++;
}
}
int main()
{
n=read(),m=read();
for (int i=1;i<=n;i++)
p[i].scan(i),q[i]=p[i];
sort(p+1,p+n+1);
to_up.insert(node(0,inf)),from_up.insert(node(0,inf));
to_down.insert(node(0,-inf)),from_down.insert(node(0,-inf));
while (finish<n)
{
int size1=to_up.size()+from_up.size();
int size2=to_down.size()+from_down.size();
//puts("ok");
if (size1==2&&size2==2)
{
if (id>n) break;
t=p[id].t,add_from();
continue;
}
if (size1>=size2)
{
node now1=*(to_up.begin());
node now2=*(from_up.begin());
if (id<=n&&p[id].t-t<now1.pos-pos&&p[id].t-t<now2.pos-pos)
{
pos+=p[id].t-t;
t=p[id].t,add_from();
}
else
{
if (now1>now2) swap(now1,now2);
t+=(ll)now1.pos-pos;
pos=now1.pos;
node now;
while ((now=*(to_up.begin())).pos==pos)
{
Ans[now.id]=t;
to_up.erase(to_up.find(now));
finish++;
}
while ((now=*(from_up.begin())).pos==pos)
{
from_up.erase(from_up.find(now));
if (q[now.id].f>pos) to_up.insert(node(now.id,q[now.id].f));
else to_down.insert(node(now.id,q[now.id].f));
}
add_from();
}
}
else
{
node now1=*(to_down.begin());
node now2=*(from_down.begin());
if (id<=n&&p[id].t-t<pos-now1.pos&&p[id].t-t<pos-now2.pos)
{
pos-=p[id].t-t;
t=p[id].t,add_from();
}
else
{
if (now1<now2) swap(now1,now2);
t+=(ll)pos-now1.pos;
pos=now1.pos;
node now;
while ((now=*(to_down.begin())).pos==pos)
{
Ans[now.id]=t;
to_down.erase(to_down.find(now));
finish++;
}
while ((now=*(from_down.begin())).pos==pos)
{
from_down.erase(from_down.find(now));
if (q[now.id].f>pos) to_up.insert(node(now.id,q[now.id].f));
else to_down.insert(node(now.id,q[now.id].f));
}
add_from();
}
}
//cout<<t<<" "<<pos<<endl;
}
for (int i=1;i<=n;i++)
printf("%lld\n",Ans[i]);
return 0;
}