zoukankan      html  css  js  c++  java
  • 【BZOJ4843】[Neerc2016]Expect to Wait 排序

    【BZOJ4843】[Neerc2016]Expect to Wait

    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个数bi(1<=bi<=1e9)表示图书馆初始有bi本书,询问所有人的等待时间之和为多少。

    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

    题解:将借书看成+x,换书看成-x,然后在时间轴上求前缀和,发现那些权值>0的线段的加权长度即时总等待时间。那么如果初始有y本书呢?则我们只需要计算所有权值>y的线段的加权长度。将所有线段排个序即可。

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    const int maxn=100010;
    int n,m,tot;
    ll sum,sv,sl;
    char str[10];
    ll ans[maxn],t[maxn];
    struct node
    {
    	ll val,len;
    }p[maxn];
    struct query
    {
    	int org;
    	ll val;
    }q[maxn];
    inline int rd()
    {
    	int ret=0,f=1;	char gc=getchar();
    	while(gc<'0'||gc>'9')	{if(gc=='-')f=-f;	gc=getchar();}
    	while(gc>='0'&&gc<='9')	ret=ret*10+gc-'0',gc=getchar();
    	return ret*f;
    }
    bool cmp1(node a,node b)
    {
    	return a.val>b.val;
    }
    bool cmp2(query a,query b)
    {
    	return a.val>b.val;
    }
    int main()
    {
    	n=rd(),m=rd();
    	int i,j,a;
    	for(i=1;i<=n;i++)
    	{
    		scanf("%s",str),t[i]=rd(),a=rd();
    		if(sum>0)	p[++tot].val=sum,p[tot].len=t[i]-t[i-1];
    		if(str[0]=='+')	a=-a;
    		sum+=a;
    	}
    	for(i=1;i<=m;i++)	q[i].val=rd(),q[i].org=i;
    	sort(p+1,p+tot+1,cmp1);
    	sort(q+1,q+m+1,cmp2);
    	for(i=j=1;i<=m;i++)
    	{
    		for(;p[j].val>q[i].val&&j<=tot;j++)	sv+=p[j].val*p[j].len,sl+=p[j].len;
    		if(q[i].val<sum)	ans[q[i].org]=-1;
    		else	ans[q[i].org]=sv-sl*q[i].val;
    	}
    	for(i=1;i<=m;i++)
    	{
    		if(ans[i]==-1)	printf("INFINITY
    ");
    		else	printf("%lld
    ",ans[i]);
    	}
    	return 0;
    }
  • 相关阅读:
    【转】ubuntu 12.04 LTS 网络配置要点
    Sqlite3在FS_S5PC100开发板上的移植
    java中常用的字符串的截取方法
    一种很好的程序调试方法!
    win7修复MBR
    .tar.xz文件的解压
    linux环境下LED驱动编程一例
    Eclipse设置:背景与字体大小和xml文件中字体大小调整
    ARM LDR与MOV的区别
    windows下从任意目录快速进入CMD
  • 原文地址:https://www.cnblogs.com/CQzhangyu/p/7434535.html
Copyright © 2011-2022 走看看