P4254 [JSOI2008]Blue Mary开公司 (李超树)

题意:插入一些一次函数线段 每次询问在x = x0处这些线段的最大值

题解:李超树模版题 维护优势线段

   注意这题的输入是x=1时的b

#include <iostream>
#include <stdio.h>
using namespace std;
const int MAXT = 50000;
#define pff pair<double, double>

int tot, rt;
char s[50];
pff t[MAXT << 5];
int ls[MAXT << 5], rs[MAXT << 5];
double ans;

double fun(pff x, int y) {
    return x.first * (1.0 * (y - 1)) + x.second;
}

void add(int &k, int l, int r, pff x) {
    if(!k) {
        k = ++tot;
        t[k] = x;
        return;
    }

    int mid = l + r >> 1;
    if(fun(t[k], l) < fun(x, l) && fun(t[k], r) < fun(x, r)) {
        t[k] = x;
        return;
    }
    if(fun(t[k], l) > fun(x, l) && fun(t[k], r) > fun(x, r)) return;

    if(t[k].first < x.first) {
        if(fun(t[k], mid) < fun(x, mid)) add(ls[k], l, mid, t[k]), t[k] = x;
        else add(rs[k], mid + 1, r, x);
    } else {
        if(fun(t[k], mid) > fun(x, mid)) add(ls[k], l, mid, x);
        else add(rs[k], mid + 1, r, t[k]), t[k] = x;
    }
    /*
    if(fun(x, mid) > fun(t[k], mid)) swap(t[k], x);
    if(fun(x, l) > fun(t[k], l)) add(ls[k], l, mid, x);
    if(fun(x, r) > fun(t[k], r)) add(rs[k], mid + 1, r, x);
    */
}

double ask(int k, int l, int r, int x) {
    //if(!k) return -(1.0 * (1 << 30));
    if(l == r) return fun(t[k], x);
    int mid = l + r >> 1;
    double res = fun(t[k], x);
    if(x <= mid) return max(res, ask(ls[k], l, mid, x));
    else return max(res, ask(rs[k], mid + 1, r, x));
}

int main() {
    int T;
    cin>>T;
    while(T--) {
        scanf("%s", s + 1);
        if(s[1] == ‘P‘) {
            double x, y;
            scanf("%lf%lf", &x, &y);
            add(rt, 1, MAXT, pff(y, x));
        } else {
            int x;
            scanf("%d", &x);
            printf("%d\n", (int)(ask(rt, 1, MAXT, x) / 100.0));
        }
    }
    return 0;
}

原文地址:https://www.cnblogs.com/lwqq3/p/12357896.html

时间: 2024-11-05 14:54:25

P4254 [JSOI2008]Blue Mary开公司 (李超树)的相关文章

[Luogu] P4254 [JSOI2008]Blue Mary开公司

题目背景 Blue Mary 最近在筹备开一家自己的网络公司.由于他缺乏经济头脑,所以先后聘请了若干个金融顾问为他设计经营方案. 题目描述 万事开头难,经营公司更是如此.开始的收益往往是很低的,不过随着时间的增长会慢慢变好.也就是说,对于一个金融顾问 iii,他设计的经营方案中,每天的收益都比前一天高,并且均增长一个相同的量 PiP_iPi?. 由于金融顾问的工作效率不高,所以在特定的时间,Blue Mary 只能根据他已经得到的经营方案来估算某一时间的最大收益.由于 Blue Mary 是很没

【BZOJ-1568】Blue Mary开公司 李超线段树 (标记可持久化)

1568: [JSOI2008]Blue Mary开公司 Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 557  Solved: 192[Submit][Status][Discuss] Description Input 第一行 :一个整数N ,表示方案和询问的总数. 接下来N行,每行开头一个单词“Query”或“Project”. 若单词为Query,则后接一个整数T,表示Blue Mary询问第T天的最大收益. 若单词为Project,则后

BZOJ 1568: [JSOI2008]Blue Mary开公司(超哥线段树)

1568: [JSOI2008]Blue Mary开公司 Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 1080  Solved: 379[Submit][Status][Discuss] Description Input 第一行 :一个整数N ,表示方案和询问的总数. 接下来N行,每行开头一个单词“Query”或“Project”. 若单词为Query,则后接一个整数T,表示Blue Mary询问第T天的最大收益. 若单词为Project,则

数据结构(线段树):BZOJ 1568 [JSOI2008]Blue Mary开公司

1568: [JSOI2008]Blue Mary开公司 Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 602  Solved: 214[Submit][Status][Discuss] Description Input 第 一行 :一个整数N ,表示方案和询问的总数. 接下来N行,每行开头一个单词“Query”或“Project”. 若单词为Query,则后接一个整数T,表示Blue Mary询问第T天的最大收益. 若单词为Project,则

1568: [JSOI2008]Blue Mary开公司

1568: [JSOI2008]Blue Mary开公司 题目描述 传送门 题目分析 简单分析可以发现就是不停给出了\(n\)条直线,要求每次给出一条直线后求出所有直线在横坐标为\(x\)时\(y\)的最大值. 李超树裸题. 不知道李超树的可以移步百度. 是代码呢 #include <bits/stdc++.h> using namespace std; #define ls rt<<1 #define rs rt<<1|1 #define mid ((l+r)/2)

bzoj千题计划219:bzoj1568: [JSOI2008]Blue Mary开公司

http://www.lydsy.com/JudgeOnline/problem.php?id=1568 写多了就觉着水了... #include<cstdio> #include<iostream> #include<algorithm> using namespace std; #define N 100001 double a[N<<2],b[N<<2]; bool have[N<<2]; long long ans; void

[JSOI2008]Blue Mary开公司

Description! Input 第一行 :一个整数N ,表示方案和询问的总数. 接下来N行,每行开头一个单词"Query"或"Project". 若单词为Query,则后接一个整数T,表示Blue Mary询问第T天的最大收益. 若单词为Project,则后接两个实数S,P,表示该种设计方案第一天的收益S,以及以后每天比上一天多出的收益P. 1 <= N <= 100000 1 <= T <=50000 0 < P < 10

bzoj1568: [JSOI2008]Blue Mary开公司 三分+二分+线段树

答案序列一定是个下凸壳,因此添加的等差数列与其之差是个单峰函数,可以先三分求出最值,再二分求出零点,然后用线段树,将得到的区间修改为一个等差数列. 这个做法应该比较好想吧,虽然比较慢…… #include<cstdio> #define Z int l=1,int r=N,int k=1 #define N 50000 #define M (l+r>>1) #define P (k<<1) #define S (k<<1|1) #define K l,r,k

bzoj1568 [JSOI2008]Blue Mary开公司

题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=1568 https://www.luogu.org/problemnew/show/P4254 思路 超哥线段树模板题 若当前线段完全高于标记线段,则将当前线段进行标记 若当前线段完全低于标记线段,则将当前线段扔掉 若当前线段与标记线段有交点,考虑在上面的一部分是一个两条线段形成的分段函数,将长的线段作为当前节点的标记,短的线段继续下放 代码 #include <iostream> #