zoukankan      html  css  js  c++  java
  • bzoj1568: [JSOI2008]Blue Mary开公司

    Description

    Input

    第一行 :一个整数N ,表示方案和询问的总数。 接下来N行,每行开头一个单词“Query”或“Project”。 若单词为Query,则后接一个整数T,表示Blue Mary询问第T天的最大收益。 若单词为Project,则后接两个实数S,P,表示该种设计方案第一天的收益S,以及以后每天比上一天多出的收益P。

    Output

    对于每一个Query,输出一个整数,表示询问的答案,并精确到整百元(以百元为单位,例如:该天最大收益为210或290时,均应该输出2)。

    Sample Input

    10
    Project 5.10200 0.65000
    Project 2.76200 1.43000
    Query 4
    Query 2
    Project 3.80200 1.17000
    Query 2
    Query 3
    Query 1
    Project 4.58200 0.91000
    Project 5.36200 0.39000

    Sample Output

    0
    0
    0
    0
    0
     
     
     
    这个样例弱到不想说什么....
    自己YY了个二分+线段树- -于是多了个log
    然后神犇说可以李超线段树
    ---------------------------

    题解:超哥线段树。

    这道题相当于是插入n条直线y=kx+b 

    然后查询某x位置所有直线中的最大值。

    我们需要用到标记永久化的思想。每次加入一条直线,先判断直线的斜率和本区间记录的直线的斜率,再判断区间中点哪条直线的答案大,如果是斜率大的直线答案大,因为斜率递增,所以在[mid+1,r]中斜率小的直线不会再产生贡献,那么我们把当前区间的答案更改为斜率大的直线,同时将斜率小的直线向[l,mid]中下方。如果是斜率小的直线的答案大,那么斜率大的直线只可能在[mid+1,r]中产生贡献,那么就把当前区间的答案更改为斜率较小的直线,并把斜率大的直线向[mid+1,r]下方。

    查询答案的时候就把经过的区间所记录的直线该点的值都计算一下,取最大值就是答案。

    来源:http://blog.csdn.net/clover_hxy/article/details/52503987

    ---------------------------
     1 #include<bits/stdc++.h>
     2 #define rep(i,l,r) for(int i=l;i<=r;++i)
     3 using namespace std;
     4 typedef double d;
     5 char s[10];
     6 const int N=2023333;
     7 d a[N],b[N],ans;
     8 int n,m,Q,tr[N],x;
     9 bool pd(int x,int y,int now){
    10     --now;
    11     return a[x]+b[x]*now>a[y]+b[y]*now;
    12 }
    13 void upd(int x,int l,int r,int now){
    14     if(l==r){
    15         if(pd(now,tr[x],l)) tr[x]=now;
    16         return;
    17     }
    18     int mid=l+r>>1;
    19     if(b[now]>b[tr[x]]){
    20         if(pd(now,tr[x],mid)) upd(x<<1,l,mid,tr[x]),tr[x]=now;
    21         else upd(x<<1|1,mid+1,r,now);
    22     }else {
    23         if(pd(now,tr[x],mid)) upd(x<<1|1,mid+1,r,tr[x]),tr[x]=now;
    24         else upd(x<<1,l,mid,now);
    25     }
    26 }
    27 void que(int x,int l,int r,int now){
    28     ans=max(ans,a[tr[x]]+b[tr[x]]*(now-1));
    29     if(l==r)return;
    30     int mid=l+r>>1;
    31     if(now<=mid)que(x<<1,l,mid,now);else que(x<<1|1,mid+1,r,now);
    32 }
    33 int main(){
    34     cin>>Q; n=500001;
    35     while(Q--){
    36         scanf("%s",s);
    37         if(s[0]=='P'){
    38             ++m;
    39             scanf("%lf%lf",&a[m],&b[m]);
    40             upd(1,1,n,m);            
    41         }else {
    42             scanf("%d",&x);
    43             ans=0;
    44             que(1,1,n,x);
    45             printf("%d
    ",(int)ans/100);
    46         }
    47     }
    48 }
    View Code
     
  • 相关阅读:
    Java集合中迭代器
    java 基础归纳总结(三)
    java 基础归纳总结(二)
    java 基础归纳总结(一)
    python之hashlib模块
    python之configparser模块
    Python之time模块
    python之os模块
    python之random模块
    python generator(生成器)
  • 原文地址:https://www.cnblogs.com/Bloodline/p/6397458.html
Copyright © 2011-2022 走看看