zoukankan      html  css  js  c++  java
  • 1568: [JSOI2008]Blue Mary开公司(超哥线段树)

    1568: [JSOI2008]Blue Mary开公司

    Time Limit: 15 Sec  Memory Limit: 162 MB
    Submit: 1198  Solved: 418

    Description

    Input

    第一行 :一个整数N ,表示方案和询问的总数。 
    接下来N行,每行开头一个单词“Query”或“Project”。 
    若单词为Query,则后接一个整数T,表示Blue Mary询问第T天的最大收益。 
    若单词为Project,则后接两个实数S,P,表示该种设计方案第一天的收益S,以及以后每天比上一天多出的收益P。
    1 <= N <= 100000 1 <= T <=50000 0 < P < 100,| S | <= 10^6 
    提示:本题读写数据量可能相当巨大,请选手注意选择高效的文件读写方式。

    Output

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

    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

    HINT

     

    Source

    分析

    超哥线段树,记录每个点的最大的线段是谁。查询时用这条线段查询。

    那么怎么记录呢,(当时这个问题困惑我好久),线段树只能记录一段区间,对于一条线段它只记录一段区间,怎么保存区间所有的线段?

    借用一张图说明这一点。

    对于原来的区间[l,r]表示y'这条线段,就是让[l,r]区间的所有的线段是y',然后来了一条线段y”,显然在x点右边,y”要比y’更优,但是线段树只能从中间劈开,不能[l,x][x,r]这样,所以我们就找到中点mid = (l+r)/2,这样[mid,r]这段区间可以直接更新了,左区间继续像这样分,全部都更新完就好了。

    code

     1 #include<cstdio>
     2 #include<algorithm>
     3 #define lson l,m,rt<<1
     4 #define rson m+1,r,rt<<1|1
     5  
     6 using namespace std;
     7  
     8 const int MAXN = 500010;
     9 int fut[MAXN<<2];
    10 double a[MAXN<<2],b[MAXN<<2];
    11 char opt[15];
    12 int tot;
    13  
    14 int pd(int x,int y,int p)
    15 {
    16     return a[x]+(p-1)*b[x] > a[y]+(p-1)*b[y];  
    17 }
    18 void update(int l,int r,int rt,int x)
    19 {
    20     if (l==r)
    21     {
    22         if (pd(x,fut[rt],l)) fut[rt] = x;
    23         return ;
    24     }
    25     int m = (l+r)>>1;
    26     if (b[x]>b[fut[rt]])
    27     {
    28         if (pd(x,fut[rt],m)) update(lson,fut[rt]), fut[rt] = x;
    29         else update(rson,x);
    30     }
    31     if (b[x]<b[fut[rt]])
    32     {
    33         if (pd(x,fut[rt],m)) update(rson,fut[rt]), fut[rt] = x;
    34         else update(lson,x);
    35     }
    36 }
    37 double getans(int k,int x)
    38 {
    39     return a[k]+(x-1)*b[k];
    40 }
    41 double query(int l,int r,int rt,int x)
    42 {
    43     if (l==r) return getans(fut[rt],x);
    44     int m = (l+r)>>1;
    45     double ans = getans(fut[rt],x);
    46     if (x<=m) ans = max(ans,query(lson,x));
    47     else ans = max(ans,query(rson,x));
    48     return ans;
    49 }
    50 int main()
    51 {
    52     int n,x;
    53     scanf("%d",&n);
    54     for (int i=1; i<=n; ++i)
    55     {
    56         scanf("%s",opt);
    57         if (opt[0]=='P')
    58         {
    59             ++tot;
    60             scanf("%lf%lf",&a[tot],&b[tot]);
    61             update(1,n,1,tot);
    62         }
    63         else
    64         {
    65             scanf("%d",&x);
    66             double t1 = query(1,n,1,x);
    67             int t2 = t1;
    68             printf("%d
    ",t2/100);
    69         }
    70     }   
    71     return 0;
    72 }
  • 相关阅读:
    Spring Boot中常用的三个注解
    Idea插件
    Java微服务 在 Linux 环境启停Shell脚本
    注解
    Oracle树状结构层级查询
    zabbix安装部署(server部分)
    zabbix监控系统客户端安装
    Windows 用bat脚本带配置启动redis,并用vb脚本使其在后台运行。
    svn cleanup failed–previous operation has not finished; run cleanup if it was interrupted
    PHP网页显示乱码问题总结
  • 原文地址:https://www.cnblogs.com/mjtcn/p/7349083.html
Copyright © 2011-2022 走看看