Codeforces Gym 101190 (NEERC 2016) E. Expect to Wait (扫描线)

来源:互联网 发布:宜人贷淘宝验证不了 编辑:程序博客网 时间:2024/05/19 23:27

题意

按时间顺序给出在某地借还车记录。

  • + t k 表示在时刻 t ,该地新增 k 辆自行车
  • - t k 表示在时刻 t ,k 个人来借车。

每个人借车必定按照来的先后顺序获得车辆,等待时间为 获得车辆的时刻 - 准备借车的时刻

对于 q 组询问,每组询问求在初始 0 时刻该地有 b 辆车的前提下,所有借车人的总等待时间?

解题思路

扫描线问题。

这里写图片描述

x 轴表示时间,y 轴表示当前等待的人数,则对于每个初始时刻有的车辆 b,重做一条 y = b 的线与区域所围成的几何图形的面积即为总的等待时间。

代码

#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>#include<cmath>#include<fstream>using namespace std;const int N = 1e5 + 10;char op;int n, q, t[N], k[N];struct Node {    int wait, len;} p[N];bool operator<(Node a, Node b)  {   return a.wait > b.wait; }struct Query {    int q, idx; long long ans;} qry[N];bool cmp(Query a, Query b) {    return a.q > b.q;   }bool cmp_idx(Query a, Query b)  {   return a.idx < b.idx;   }int main(){    freopen("expect.in", "r", stdin);    freopen("expect.out", "w", stdout);    scanf("%d %d",&n,&q);    for(int i=1;i<=n;i++) {        scanf(" %c %d %d", &op, &t[i], &k[i]);        if(op == '+')   k[i] *= -1;    }    int wait = k[1];    for(int i=2;i<=n;i++)    {        p[i-1].wait = wait;        p[i-1].len = t[i]-t[i-1];        wait += k[i];    }    wait = max(0, wait);    sort(p+1, p+n);    for(int i=1;i<=q;i++)        scanf("%d", &qry[i].q), qry[i].idx = i;    sort(qry+1, qry+q+1, cmp);    qry[0].q = qry[1].q;    long long ans = 0,  len = 0;    int idx = 1;    for(int i=1;i<=q;i++)    {        if(qry[i].q < wait) {   qry[i].ans = -1;    continue;   }        ans += len * (qry[i-1].q - qry[i].q);        while(idx < n && p[idx].wait > qry[i].q) {            ans += (long long)(p[idx].wait - qry[i].q) * p[idx].len;            len += p[idx].len;            idx++;        }        qry[i].ans = ans;    }    sort(qry+1, qry+q+1, cmp_idx);    for(int i=1;i<=q;i++)        if(qry[i].ans == -1)    printf("INFINITY\n");        else    printf("%I64d\n", qry[i].ans);}
阅读全文
0 0