[BZOJ]4843: [Neerc2016]Expect to Wait 数形结合

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/baidu_36797646/article/details/85222801

Description

ls最近开了一家图书馆,大家听说是ls开的,纷纷过来借书,自然就会出现供不应求的情况,并且借书的过程类似一个队列,每次有人来借书就将它加至队尾,每次有人来还书就把书借给队头的若干个人,定义每个人的等待时间为拿到书的时刻减去加至队列的时刻,如果一个人根本就拿不到书,则等待时间为inf,现在给出所有时刻借书还书的情况,和若干个询问,每次询问当图书馆初始有x本书时所有人的等待时间之和是多少(如果存在一个人根本拿不到书,则输出INFINITY)。

题解:

好题啊!可以建个坐标系,x轴是时间轴,y轴代表当前这个时间点还有多少个人在等待借书,然后x轴上面的面积就是答案,如果初始的书数不同,那么也就是起点不同。一开始有 x x 本书,那么起点就为 ( 0 , x ) (0,-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]);
}

猜你喜欢

转载自blog.csdn.net/baidu_36797646/article/details/85222801