Gym 101190E (NEERC2016) Expect to Wait

来源:互联网 发布:java api 1.7中文版 编辑:程序博客网 时间:2024/06/05 08:47

Gym 101190E (NEERC2016) Expect to Wait

扫描线

传送门:HustOJ

题意

给你n个共享单车的 [借/还,数量,时间]。有q个查询,每个查询表示若初始有m个单车,那么所有人的等待时间总和是多少。

思路

%%%

首先得看出来这是个扫描线。。。
然后跟普通扫描线不同的是:从y轴扫下来时,x的长度只增不减。所以不需要用线段树维护边,只要扫一遍边集,每次加一下面积就可以了。

存边时存横边的y值和长度,扫描时用一个平行于x轴的线从y方向扫下来。每遇到一条边,更新面积。

代码

注意开数组要开2105,因为n和q的边都存进去了

#include <cstdio>#include <cstdlib>#include <iostream>#include <algorithm>#include <string>#include <cstring>#include <vector>#include <cmath>#include <queue>#include <stack>#include <set>#include <map>#include <iomanip>#define _ ios_base::sync_with_stdio(0),cin.tie(0)#define M(a,b) memset(a,b,sizeof(a))#define N n#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1using namespace std;const int MAXN=200007;const int oo=0x3f3f3f3f;typedef long long LL;const LL loo=4223372036854775807ll;typedef long double LB;const LL mod=1e9+7;const double eps=1e-6;struct Line{    int k;LL x; LL y;    Line() { k=x=y=0; }    Line(int _a, LL _b, LL _c) { k=_a, x=_b, y=_c; }    bool operator < (const Line &t) const    {        if(y!=t.y)            return y>t.y;        else return k>t.k;    }}l[MAXN];LL res[MAXN];int main(){    //freopen("expect.in", "r", stdin);    //freopen("expect.out", "w", stdout);    int n, m;    while(scanf("%d%d", &n, &m)==2)    {        LL last1=0, last2=0;LL now=0;LL ma=-oo;        for(int i=0;i<n;i++)        {            char c;LL ta, tb;            scanf(" %c %lld %lld", &c, &ta, &tb);            if(c=='-')            {                l[now]=Line(1, ta-last2, last1);                last1+=tb;            }            else            {                l[now]=Line(1, ta-last2, last1);                last1-=tb;            }            ma=max(ma, last1);            last2=ta;            now++;        }        for(int i=0;i<m;i++)        {            LL tmp;scanf("%lld", &tmp);            l[now++]=Line(2, i, tmp);            if(tmp<last1) res[i]=-1;        }        sort(l, l+now);        LL ans=0, k=0, lastk=ma;        for(int i=0;i<now;i++)        {            ans+=(lastk-l[i].y)*k;            if(l[i].k==1)            {                k+=l[i].x;            }            else            {                if(res[l[i].x]!=-1) res[l[i].x]=ans;            }            lastk=l[i].y;        }        for(int i=0;i<m;i++)        {            if(res[i]==-1) printf("INFINITY\n");            else printf("%lld\n", res[i]);        }    }    return 0;}
原创粉丝点击