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

    1568: [JSOI2008]Blue Mary开公司

    Time Limit: 15 Sec  Memory Limit: 162 MB
    Submit: 1100  Solved: 386
    [Submit][Status][Discuss]

    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
    超哥线段树

    线段树的每个结点上存的是这个区间对应的一条线段。

    插入时,新线段完全更劣,则不进行修改

    新线段完全更优,替换旧线段,向下update,若部分更优,把优的部分多的那条线段留在这个结点,

    把另一条线段较优的那部分截出来,更新该节点子树

    #include<algorithm>
    #include<iostream>
    #include<cstdio>
    using namespace std;
    #define N 500004
    double a[N*2],b[N*2];
    int tree[N*4],n,cnt=0;
    
    inline bool check(int i,int j,int k) 
    {
        return a[i]+b[i]*(k-1)>a[j]+b[j]*(k-1);
    }
    inline double calc(int k,int x)
    {
        return (a[k]+b[k]*(x-1));
    }
    void modify(int l,int r,int rt,int x)
    {
        if(l==r)
        {
            if(check(x,tree[rt],l)) tree[rt]=x;
            return;
        }
        int mid=(l+r)>>1;
        if(b[x]>b[tree[rt]])
        {
            if(check(x,tree[rt],mid)) modify(l,mid,rt<<1,tree[rt]),tree[rt]=x;
            else modify(mid+1,r,rt<<1|1,x);
        } 
        if(b[x]<=b[tree[rt]])
        {
            if(check(x,tree[rt],mid))modify(mid+1,r,rt<<1|1,tree[rt]),tree[rt]=x;
                else modify(l,mid,rt<<1,x);
        }
     } 
    double query(int l,int r,int rt,int x)
    {
        if(l==r) return calc(tree[rt],x);
        int mid=(l+r)>>1;
        double ans = calc(tree[rt],x);
        if(x<=mid) ans=max(ans,query(l,mid,rt<<1,x));
        if(x>mid)ans=max(ans,query(mid+1,r,rt<<1|1,x));
        return ans;
    }
    int main()
    {
        scanf("%d",&n);
        char s[20];
        while(n--)
        {
            scanf("%s",s);
            if(s[0]=='P')
            {
                
                scanf("%lf%lf",&a[cnt],&b[cnt]);
                modify(1,N,1,cnt);
            }
            else {
                int x;
                
                scanf("%d",&x);
                double tmp=query(1,N,1,x);
                int ans=tmp/100.00;
                printf("%d
    ",ans);
            }
        }
        return 0;
    }
  • 相关阅读:
    POJ 3140 Contestants Division (树dp)
    POJ 3107 Godfather (树重心)
    POJ 1655 Balancing Act (树的重心)
    HDU 3534 Tree (经典树形dp)
    HDU 1561 The more, The Better (树形dp)
    HDU 1011 Starship Troopers (树dp)
    Light oj 1085
    Light oj 1013
    Light oj 1134
    FZU 2224 An exciting GCD problem(GCD种类预处理+树状数组维护)同hdu5869
  • 原文地址:https://www.cnblogs.com/sssy/p/7309772.html
Copyright © 2011-2022 走看看