1. 程式人生 > >101190E Expect to Wait(數形結合 , 二分, 查分)

101190E Expect to Wait(數形結合 , 二分, 查分)

題意:

告訴你n 個操作過程, + 代表 在t 時刻來了k 個車,  - 代表在t 時刻 來了k 個人,  每個人都要開走車, 沒車的話 一直在佇列裡等, 告訴你每一天開始有多少輛車, 求所有人的等待時間總和, 如果有人拿不到車就輸出 inf。

思路:

數形結合的思想。

n 個操作可以分成n-1 段, 記錄每一段的人和 等待時間。

那麼一開始有x 輛車的話, 那麼只需要將大於x 的段減掉x 乘以等待時間即可。

那麼這樣 與每一段的順序無關, 直接按照人排序, 然後列舉x, 二分查詢左邊界, 做個字首和 差分即可。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <string>
#include <iostream>
#include <cctype>
#include <sstream>
#include <vector>
using namespace std;
const int maxn = 100005;


struct node1{
    char cmd[4];
    int t, k;
}p[maxn];

struct node{
    int num, len;

}nod[maxn];

bool cmp(const node& lhs, const node& rhs){
    return lhs.num < rhs.num;
}
long long pre[maxn];
long long pre1[maxn];

int main(){
    freopen("expect.in","r",stdin);
    freopen("expect.out","w", stdout);

    int n,q;
    while(~scanf("%d %d",&n, &q)){
        int x, y;
        int sum = 0;
        long long peo = 0LL;
        for (int i = 0; i < n; ++i){
            scanf("%s%d%d", p[i].cmd, &p[i].t, &p[i].k);
            if (p[i].cmd[0] == '-'){
                peo += p[i].k;
            }
            else {
                peo -= p[i].k;
            }
        }
        if (p[0].cmd[0] == '-')
            sum = p[0].k;
        else
            sum = -p[0].k;
        int cnt = 0;
        for (int i = 1; i < n; ++i){
            nod[++cnt].num = sum;
            nod[cnt].len = p[i].t - p[i-1].t;
            if (p[i].cmd[0] == '-'){
                sum += p[i].k;
            }
            else {
                sum -= p[i].k;
//                sum = max(sum, 0);
            }
        }

        sort(nod + 1, nod + cnt + 1, cmp);


        for (int i = 1; i <= cnt; ++i){
            pre[i] = pre[i-1] + (long long)nod[i].num * nod[i].len;
            pre1[i] = pre1[i-1] + nod[i].len;
        }

//
//        for (int i = 1; i <= cnt; ++i){
//            printf("%d %d\n", nod[i].num, nod[i].len);
//
//        }
//        printf("peo = %lld\n", peo);

        for (int i = 0; i < q; ++i){
            long long ans = 0LL;
            int x;
            scanf("%d",&x);

            if (x < peo) {
                printf("INFINITY\n");
                continue;
            }
            int l = 1, r = cnt;
            while (l <= r){
                int m = l + r >> 1;
                if (nod[m].num > x){
                    r = m - 1;
                }
                else {
                    l = m + 1;
                }
            }
//            printf("r = %d\n", r);
            ans = (pre[cnt] - pre[r]) - x * (pre1[cnt] - pre1[r]);
            printf("%I64d\n", ans);
        }
    }
    return 0;
}

/**
This is ACM North Eastern European Regional Contest,
sponsored by International Business Machines.
The. Best. Contest. Ever.
A Great Opportunity for all contestants.
ab Ab A Abc AB Abcd ABc Abcde AbC
Oh  No  Extra Spaces.And,Punctuation Ruin Everything
10 4 1 2
1 2 3 4 5 6 7 8 9 10
10 9 8 7 6 5 4 3 2 1
EEESEEEESS
68


6  100
- 2 3
- 4 3
+ 5 2
+ 7 4
- 10 3
+ 13 3


6  100
- 2 3
- 4 3
+ 5 2
+ 7 4
- 10 3
+ 13 3


5 100
+ 2 1
+ 4 2
+ 5 3
+ 9 10
+ 10 11

**/