zoukankan      html  css  js  c++  java
  • BZOJ 4843

    这道题卡了我好久,一开始的思路可能有点问题,导致后面越来越乱....

    一开始我是这样想的,对于每个人,他的等待时间是他拿到书的时间减去他借书的时间,那么总等待时间就是所有人拿到书的时间减去所有人借书的时间,我们维护书的数目,然后发现对于一次还书,它的贡献是有些人在此刻拿到书,对于一次借书,它的贡献就是有些人在此刻借书,然后离线搞一搞...后来发现这种写法细节颇多,然后就弃疗了.

    后来的思想是我们把等待时间看成一段一段的,对于每个前缀和为负的位置,说明有这么多个人还没拿到书,那么这么多个人就一定要等这一段时间,这样的话我们就离线排个序,然后维护前缀和的正负和答案的变化量,这样就比较好搞了。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 #define maxn 100005
     6 typedef long long LL;
     7 LL ans[maxn],cur,sumt;
     8 int n,q;
     9 pair<int,int> A[maxn],B[maxn];
    10 
    11 inline int read(void) 
    12 {
    13     int x=0;
    14     char ch=getchar();
    15     while (ch>'9'||ch<'0') ch=getchar();
    16     while (ch<='9'&&ch>='0') 
    17     {
    18         x=x*10+ch-'0';
    19         ch=getchar();
    20     }
    21     return x;
    22 }
    23 
    24 void init(void) 
    25 {
    26     for (int i=1;i<=n;i++) A[i].first+=A[i-1].first;
    27     for (int i=1;i<n;i++) A[i].second=A[i+1].second-A[i].second;
    28     sort(B+1,B+q+1);
    29     int pp=1,p=n;
    30     while (B[pp].first+A[n].first<0&&pp<=q) ans[B[pp].second]=-1,pp++;
    31     sort(A+1,A+n+1);
    32     while (A[p].first+B[pp].first>=0&&p>=1) p--;
    33     for (int i=1;i<=p;i++) 
    34     {
    35         sumt+=A[i].second;
    36         cur-=(LL)A[i].second*(A[i].first+B[pp].first);
    37     }
    38     ans[B[pp].second]=cur;
    39     for (int i=pp+1;i<=q;i++) 
    40     {
    41         while (B[i].first+A[p].first>=0&&p>=1) 
    42         {
    43             sumt-=A[p].second;
    44             cur+=(LL)(B[i-1].first+A[p].first)*A[p].second;
    45             p--;
    46         }
    47         cur-=sumt*(B[i].first-B[i-1].first);
    48         ans[B[i].second]=cur;
    49     }
    50 }
    51 
    52 int main()
    53 {
    54     n=read();q=read();
    55     for (int i=1;i<=n;i++) 
    56     {
    57         char s[3];
    58         scanf("%s",s);
    59         A[i].second=read();
    60         A[i].first=read();
    61         if (s[0]=='-') A[i].first=-A[i].first;
    62     }
    63     for (int i=1;i<=q;i++) B[i].first=read(),B[i].second=i;
    64     init();
    65     for (int i=1;i<=q;i++)
    66         if (ans[i]==-1) puts("INFINITY");
    67         else printf("%lld\n",ans[i]);
    68     return 0;
    69 }
  • 相关阅读:
    复变函数
    abc136
    点集
    一些数学题
    牛客多校第六场
    牛客多校第五场G
    复数
    generator 1
    digits 2
    Winner
  • 原文地址:https://www.cnblogs.com/lvyouyw/p/6868531.html
Copyright © 2011-2022 走看看