zoukankan      html  css  js  c++  java
  • bzoj4843 [Neerc2016]Expect to Wait

    [Neerc2016]Expect to Wait

    Time Limit: 10 Sec Memory Limit: 128 MB

    Description

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

    Input

    第一行两个整数(n,q(1<=n,q<=100000)),表示有(n)个时刻有借书还书的情况,以及有(q)个询问。
    接下来(n)行,每行表示一个操作,操作如下:
    1.$"+ t k" $ 在(t)时刻有(k)本书被还回来。
    2.("- t k")(t)时刻有(k)个人来借书。
    ((1<=t<=1e9,1<=k<=10000))
    输入顺序保证t递增。
    接下来一行(q)个数,第(i)个数(b_i(1<=b_i<=1e9))表示图书馆初始有(b_i)本书,询问所有人的等待时间之和为多少。

    Output

    一共(q)行,每行一个数表示等待时间之和,如果存在一个人根本拿不到书,则输出INFINITY。

    Sample Input

    (5 4)
    (- 1 1)
    (- 2 2)
    (+ 4 1)
    (- 6 1)
    (+ 7 2)
    (0 3 1 2)

    Sample Output

    (INFINITY)
    (0)
    (8)
    (3)

    不要问我为什么是数据结构。。。。据说可以用线段树???(雾)
    好了,来讲一讲这道题。。。。
    最开始头是真的铁。。。。。我就要在线操作。。。。我就要!!!!
    凉凉夜色为你思念成河????
    然后我们只有来重新看这道题。。。。
    我们首先把这道题转化一下,我们用正数和负数来分别表示两种情况。。。。正数的意思是你现在有多少本书。。。。负数的意思是现在有多少个人在等。。。。。
    感觉很友好的翻译了一下题目。
    那么我们要求的是一个数列中,有多少个小于0的数(每个数分别乘上它对应的权值)。
    然而你会发现不是那么友好。。。。显然坑坑洼洼,七零八碎的。。。。怎么统计啊。。。。
    但是你又会发现每次询问都是对于整个数列的,,整个,,整个。。。。。。
    也就是说,数列的顺序并没有什么影响。
    排序啊!!!!
    排序的好处在于,整个数列是单调递增的以后,需要你统计的答案就变成连续一段的了。。。
    维护前缀和来统计答案吧。。。。。
    把询问离线下来,排个序。也满足单调性啦~~~
    具体看代码的啦(结构体有一点鬼畜,yy一下就好)

    
    #include<bits/stdc++.h>
    using namespace std;
    const int maxn = 1e5 + 5;
    struct lpl{
    	int num, len;
    	bool operator < (const lpl &aaa)const{
    		return num < aaa.num;
    	}
    }a[maxn], b[maxn], lin[maxn];
    int n, q, last, cnt;
    long long ans[maxn], s[maxn], sl[maxn];
    char mark[911];
    
    inline void putit()
    {
    	scanf("%d%d", &n, &q);
    	for(int i = 1; i <= n; ++i){
    		scanf("%s%d%d", mark, &lin[i].num, &lin[i].len);
    		if(mark[0] == '-') lin[i].len = -lin[i].len;
    		a[i].num = a[i - 1].num + lin[i].len; 
    		a[i - 1].len = lin[i].num - lin[i - 1].num;
    	}
    }
    
    inline void workk()
    {
    	last = a[n].num; sort(a + 1, a + n + 1);
    	for(int i = 1; i <= n; ++i){
    		s[i] = s[i - 1] + (long long)a[i].num * a[i].len;
    		sl[i] = sl[i - 1] + a[i].len;
    	}
    	for(int i = 1; i <= q; ++i)	scanf("%d", &b[i].num), b[i].len = i;
    	sort(b + 1, b + q + 1); int cnt = n;
    	for(int i = 1; i <= q; ++i){
    		if(last + b[i].num < 0){ans[b[i].len] = -1; continue;}
    		while(cnt && a[cnt].num + b[i].num > 0) cnt--;
    		ans[b[i].len] = -s[cnt] - b[i].num * sl[cnt];
    	}
    	
    }
    
    inline void print()
    {
    	for(int i = 1; i <= q; ++i)
    		if(ans[i] == -1) printf("INFINITY
    ");
    		else printf("%lld
    ", ans[i]);
    }
    
    int main()
    {
    	putit();	
    	workk();
    	print();
    	return 0;
    }
    
    
    心如花木,向阳而生。
  • 相关阅读:
    初步学习vue.js
    ie兼容CSS3渐变写法
    关于javascript dom扩展:Selector API
    jquery 性能优化高级技巧
    三行代码CSS竖向居中
    JS中 (function(){...})()立即执行函数
    Null 和 undefined 的区别
    CSS 交集选择器和并集选择器
    Vue-cli 构建项目后 npm run build 如何在本地运行查看
    Cubic-bezier 曲线
  • 原文地址:https://www.cnblogs.com/LLppdd/p/8655749.html
Copyright © 2011-2022 走看看