【BZOJ-1568】Blue Mary开公司 李超线段树 (标记永久化)
1568: [JSOI2008]Blue Mary开公司
Time Limit: 15 Sec Memory Limit: 162 MB
Submit: 557 Solved: 192
[Submit][Status][Discuss]
Description

Input
第一行 :一个整数N ,表示方案和询问的总数。 接下来N行,每行开头一个单词“Query”或“Project”。 若单词为Query,则后接一个整数T,表示Blue Mary询问第T天的最大收益。 若单词为Project,则后接两个实数S,P,表示该种设计方案第一天的收益S,以及以后每天比上一天多出的收益P。
Output
对于每一个Query,输出一个整数,表示询问的答案,并精确到整百元(以百元为单位,例如:该天最大收益为210或290时,均应该输出2)。
Sample Input
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
HINT
约定: 1 <= N <= 100000 1 <= T <=50000 0 < P < 100,| S | <= 10^6 提示:本题读写数据量可能相当巨大,请选手注意选择高效的文件读写方式。
Source
Solution
李超线段树,对于插入,相当于是在根插入,标记永久化,即标记不下推,每个点标记唯一
可能个人理解有不对,欢迎指导
UPD:找到一个不错的讲解:
不妨考虑标记永久化(这里只是一定程度上的永久化但还是要下传的)。让线段树中的一个节点只对应一条直线,那么如果在这个区间加入一条直线怎么办呢?要分类讨论,设新加入的f1(x)=k1x+b1,原来的f2(x)=k2x+b2,左端点为l,右端点为r,那么有:
1.f1(d[l])<f2(d[l])且f1(d[r])<f2(d[r]),对应一条直线在两个端点都比另一条小,那么显然在l~r中f1(x)处处比f2(x)小,直接把f2(x)替换为f1(x);
2.同理若上式的两个符号都为>,那么f1(x)处处不如f2(x)优,不做更改。
3.k1<k2,那么由于不满足1.2,显然两条直线有交点,此时解不等式f1(x)<f2(x)得到x>(b1-b2)/(k2-k1),那么判断(b1-b2)/(k2-k1)在左半区间还是右半区间递归下传即可;
4.k1>k2同理。
Code
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
int read()
{
int x=,f=; char ch=getchar();
while (ch<'' || ch>'') {if (ch=='-') f=-; ch=getchar();}
while (ch>='' && ch<='') {x=x*+ch-''; ch=getchar();}
return x*f;
}
int N,M;
struct LineNode
{
double k,b; int id;
LineNode(int x0=,int y0=,int x1=,int y1=,int ID=)
{
id=ID;
if (x0==x1) k=,b=max(y0,y1);
else k=(double)(y0-y1)/(x0-x1),b=(double)y0-k*x0;
}
double getf(int x) {return k*x+b;}
};
bool cmp(LineNode A,LineNode B,int x)
{
if (!A.id) return ;
return A.getf(x)!=B.getf(x)?A.getf(x)<B.getf(x):A.id<B.id; //比较值直线A,B在x的值,如果A<B返回1
}
#define maxn 50010
LineNode tree[maxn<<];
LineNode Query(int now,int l,int r,int x)
{
if (l==r) return tree[now];
int mid=(l+r)>>; LineNode tmp;
if (x<=mid) tmp=Query(now<<,l,mid,x);
else tmp=Query(now<<|,mid+,r,x);
return cmp(tree[now],tmp,x)?tmp:tree[now];
}
void insert(int now,int l,int r,LineNode x)
{
if (!tree[now].id) tree[now]=x;
if (cmp(tree[now],x,l)) swap(tree[now],x);
if (l==r || tree[now].k==x.k) return;
int mid=(l+r)>>; double X=(tree[now].b-x.b)/(x.k-tree[now].k);//求交点,X为交点横坐标,判断下放区间
if (X<l || X>r) return;
if (X<=mid) insert(now<<,l,mid,tree[now]),tree[now]=x;
else insert(now<<|,mid+,r,x);
}
void Insert(int now,int l,int r,int L,int R,LineNode x)
{
if (L<=l && R>=r) {insert(now,l,r,x); return;}
int mid=(l+r)>>;
if (L<=mid) Insert(now<<,l,mid,L,R,x);
if (R>mid) Insert(now<<|,mid+,r,L,R,x);
}
int main()
{
M=read(); N=;
char opt[];
while (M--)
{
scanf("%s",opt);
if (opt[]=='P')
{
double K,B; scanf("%lf%lf",&K,&B);
LineNode tmp; tmp.k=B; tmp.b=K-B; tmp.id=;
Insert(,,N,,N,tmp);
}
int x;
if (opt[]=='Q') x=read(),printf("%lld\n",(long long)(Query(,,N,x).getf(x)/+1e-));
}
return ;
}
参照着zky学长的模板打的...中间有好多问题,慢慢就特别相似了(捂脸)
【BZOJ-1568】Blue Mary开公司 李超线段树 (标记永久化)的更多相关文章
- JSOI2008 Blue Mary开公司 | 李超线段树学习笔记
题目链接:戳我 这相当于是一个李超线段树的模板qwqwq,题解就不多说了. 代码如下: #include<iostream> #include<cstdio> #include ...
- [bzoj1568][JSOI2008]Blue Mary开公司——李超线段树
题目大意 题解 这道题需要用到一种叫做李超线段树的东西.我对于李超线段树,是这样理解的: 给节点打下的标记不进行下传,而是仅仅在需要的时候进行下传,这就是所谓永久化标记. 对于这道题,借用一张图, 这 ...
- BZOJ.1568.[JSOI2008]Blue Mary开公司(李超线段树)
题目链接 线段树每个节点记录\(f(mid)\)最大的直线(在\(mid\)处函数值最大的直线),称作优势线段(还是直线啊...无所谓了). 如果是在区间插入线段会影响\(O(\log n)\)个区间 ...
- BZOJ-1568: Blue Mary开公司 (李超线段树)
Description Input 第一行 :一个整数N ,表示方案和询问的总数. 接下来N行,每行开头一个单词“Query”或“Project”. 若单词为Query,则后接一个整数T,表示Blue ...
- [JSOI2008]Blue Mary开公司[李超线段树]
题面 bzoj luogu 好久以前听lxl讲过 咕掉了.. 竟然又遇到了 安利blog #include <cmath> #include <cstring> #includ ...
- BZOJ 1568 Blue Mary开公司
李超线段树. GTMD调了一下午... #include<iostream> #include<cstdio> #include<cstring> #include ...
- 2019.02.11 bzoj1568: [JSOI2008]Blue Mary开公司(线段树)
传送门 题意简述:维护整体加一条线段,求单点极值. 思路: 直接上李超线段树维护即可. 代码: #include<bits/stdc++.h> #define ri register in ...
- bzoj 1513 POI2006 Tet-Tetris 3D 二维线段树+标记永久化
1511: [POI2006]OKR-Periods of Words Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 351 Solved: 220[S ...
- P4254 [JSOI2008]Blue Mary开公司 (李超树)
题意:插入一些一次函数线段 每次询问在x = x0处这些线段的最大值 题解:李超树模版题 维护优势线段 注意这题的输入是x=1时的b #include <iostream> #includ ...
随机推荐
- checkbox与jq<转>2
jQuery中attr()解决checked属性问题 作者:u012885111 这两天在做一个表单提交,其中就包含有checkbox的全选和反选,这是最先开始做出来的版本,代码如下: <inp ...
- redis-cache中的callback
这个是mybatis/redis-cache中关键类 RedisCache 的源码 /** * Copyright 2015 the original author or authors. * * ...
- 如何迁移Alwayson AG
Windows cluster要求同一个cluster中的所有windows版本都是相同的,这样就出现一个问题,当我们要将对windows进行升级时,(例如从windows 2008 R2升级到win ...
- NOI2018准备 Day11
今天7点半到9点我都不知道自己在干啥, 一共A了3道题,2道钻石,1道大师. 下午调一道线段树3个小时没调出来,一个单调栈2小时没搞出来...... 学了个算法:求极大子矩阵. 昨天定的目标是学指针, ...
- 前端见微知著AngularJS备忘篇:温故而知新,可以为师矣
话说以前JQuery刚出来的时候,真的是对个人的冲击蛮大的.记得当时我买的第一本书就是<锋利的JQuery>,藉由这本书开始,我从此以后的项目基本用上了JQuery,其给我带来的便利性是不 ...
- 前端见微知著工具篇:Bower组件管控
在上一篇文章中,我们提到了利用Grunt可以完成的内容,其中最主要的功能就是利用各种Node的组件来搭配出一个自动化高亮,自动化运行等的Web前端开发环境.但是Bower也是一个专门来管理各种依赖组件 ...
- 制作鼠标移动到div上面显示弹出框
<div class="show-dialog hide"> <header> <div class="note"> < ...
- 十分钟掌握Activity的生命周期与启动模式
1. Activity的生命周期 正常情况下的Activity生命周期如下图所示(来自Android Developer): 当资源相关的系统配置变更时(比如设备屏幕方向改变,键盘可见性变化),会导致 ...
- ALinq Dynamic 使用指南——代码的获取与编译
1.下载代码 ALinq Dynamic 项目托管在 CodePlex 网站,你可以使用浏览器下载压缩包,或者通过 SVN 获取. 项目网址:http://esql.codeplex.com/ 压缩包 ...
- VC维含义
VC维含义的个人理解 有关于VC维可以在很多机器学习的理论中见到,它是一个重要的概念.在读<神经网络原理>的时候对一个实例不是很明白,通过这段时间观看斯坦福的机器学习公开课及相关补充材料, ...