版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/baidu_36797646/article/details/85222801
Description
ls最近开了一家图书馆,大家听说是ls开的,纷纷过来借书,自然就会出现供不应求的情况,并且借书的过程类似一个队列,每次有人来借书就将它加至队尾,每次有人来还书就把书借给队头的若干个人,定义每个人的等待时间为拿到书的时刻减去加至队列的时刻,如果一个人根本就拿不到书,则等待时间为inf,现在给出所有时刻借书还书的情况,和若干个询问,每次询问当图书馆初始有x本书时所有人的等待时间之和是多少(如果存在一个人根本拿不到书,则输出INFINITY)。
题解:
好题啊!可以建个坐标系,x轴是时间轴,y轴代表当前这个时间点还有多少个人在等待借书,然后x轴上面的面积就是答案,如果初始的书数不同,那么也就是起点不同。一开始有
本书,那么起点就为
。可能有点抽象,上个样例的图(开始有1本书):
代码:
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define pa pair<int,int>
const int Maxn=100010;
const int inf=2147483647;
int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
return x*f;
}
int n,q;LL ans[Maxn],Ans=0,tot=0;
struct Line{int h,l,r;}L[Maxn];
bool cmpL(Line a,Line b){return a.h>b.h;}
struct Query{int id,x;}Q[Maxn];
bool cmpQ(Query a,Query b){return a.x>b.x;}
int main()
{
n=read(),q=read();
int now=0,tn;
for(int i=1;i<=n;i++)
{
char op[3];int t,k;
scanf("%s",op);
t=read(),k=read();
if(op[0]=='-')now+=k;
else now-=k;
L[i].h=now;L[i].l=t;L[i-1].r=t;
}L[n].r=inf;tn=now;
for(int i=1;i<=q;i++)Q[i].x=read(),Q[i].id=i;
sort(L+1,L+1+n,cmpL);sort(Q+1,Q+1+q,cmpQ);
now=0;
for(int i=1;i<=q;i++)
{
if(i!=1)Ans+=((LL)Q[i-1].x-Q[i].x)*tot;
while(now<n&&L[now+1].h>Q[i].x)
{
now++;
Ans+=((LL)L[now].h-Q[i].x)*((LL)L[now].r-L[now].l);
tot+=((LL)L[now].r-L[now].l);
}
ans[Q[i].id]=Ans;
}
for(int i=1;i<=q;i++)if(Q[i].x<tn)ans[Q[i].id]=-1;
for(int i=1;i<=q;i++)
if(ans[i]==-1)puts("INFINITY");
else printf("%lld\n",ans[i]);
}