BZOJ-1568: 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
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
约定: 1 <= N <= 100000 1 <= T <=50000 0 < P < 100,| S | <= 10^6
提示:本题读写数据量可能相当巨大,请选手注意选择高效的文件读写方式。
题意:给定多个线段,以及多个询问,回答的是在某个位置,线段最高的值。
思路:当年题解好像是splay。后来可以用超哥线段树来做。
超哥线段树的节点node保存的是某线段X的id,当且当这个线段X的在这个节点node代表的区间的中点处最高(或者最低),比如下图的1线段在Mid处最高。
更新的时候(加入新的线段Y),如果它在node的mid位置比原来的线段在mid位置高,那么Y会取代原来的值。但是原来的值或者Y可能在左区间或者右区间可以最高,所以需要下推。 下面给个妮子:
假设此node原来保存的是线段2,现在加线段1,发现1线段的Mid大于2,所以替换。但是发现2线段在左边部分有一段是最高的,所以需要用2线段去更新左半部分。即更新部分有4种情况:
void update(int Now,int L,int R,int x)
{
int Mid=(L+R)>>;
if(L==R){ if(comp(x,Mx[Now],Mid)) Mx[Now]=x; return ; }
if(p[x]>p[Mx[Now]]){
//下传的时候是传的可以更新的区域(左或者右),更新的val是哪个区域可能大的那个(x或者Mx[Now])
if(comp(x,Mx[Now],Mid)) update(Now<<,L,Mid,Mx[Now]),Mx[Now]=x;
else update(Now<<|,Mid+,R,x);
}
if(p[x]<p[Mx[Now]]){
if(comp(x,Mx[Now],Mid)) update(Now<<|,Mid+,R,Mx[Now]),Mx[Now]=x;
else update(Now<<,L,Mid,x);
}
}
或者更直观的版本:
void update(int Now,int L,int R,int x)
{
int Mid=(L+R)>>;
if(L==R){ if(comp(x,Mx[Now],Mid)) Mx[Now]=x; return ; }
if(comp(x,Mx[Now],Mid)){ //只针对着两条线段比较
if(comp(Mx[Now],x,L)) update(Now<<,L,Mid,Mx[Now]); //任然是比较这两条线段
if(comp(Mx[Now],x,R)) update(Now<<|,Mid+,R,Mx[Now]);
Mx[Now]=x;
}
else {
if(comp(x,Mx[Now],L)) update(Now<<,L,Mid,x);
if(comp(x,Mx[Now],R)) update(Now<<|,Mid+,R,x);
}
}
而查询位置x的时候,从根到L==R==x这个过程都要去更新最大值。
#include<bits/stdc++.h>
using namespace std;
const int maxn=,M=;
int n,Mx[maxn*],cnt;
double s[maxn*],p[maxn*];
int comp(int x,int y,int pos) { return s[x]+(pos-)*p[x]>s[y]+(pos-)*p[y];}
double getans(int x,int pos){ return s[x]+(pos-)*p[x]; }
void update(int Now,int L,int R,int x)
{
int Mid=(L+R)>>;
if(L==R){ if(comp(x,Mx[Now],Mid)) Mx[Now]=x; return ; }
if(p[x]>p[Mx[Now]]){
if(comp(x,Mx[Now],Mid)) update(Now<<,L,Mid,Mx[Now]),Mx[Now]=x;
else update(Now<<|,Mid+,R,x);
}
if(p[x]<p[Mx[Now]]){
if(comp(x,Mx[Now],Mid)) update(Now<<|,Mid+,R,Mx[Now]),Mx[Now]=x;
else update(Now<<,L,Mid,x);
}
}
double query(int Now,int L,int R,int pos)
{
if(L==R) return getans(Mx[Now],pos);
int Mid=(L+R)>>; double ans=getans(Mx[Now],pos);
if(pos<=Mid) return max(ans,query(Now<<,L,Mid,pos));
else return max(ans,query(Now<<|,Mid+,R,pos));
}
int main()
{
int N; scanf("%d",&N);
while(N--){
char c[]; scanf("%s",c);
if(c[]=='P'){
cnt++; scanf("%lf%lf",&s[cnt],&p[cnt]);
update(,,M,cnt);
}
else {
int x; scanf("%d",&x);
double ans=query(,,M,x);
printf("%d\n",(int)ans/);
}
}
return ;
}
更直观的版本2:
#include<bits/stdc++.h>
using namespace std;
const int maxn=,M=;
int n,Mx[maxn*],cnt;
double s[maxn*],p[maxn*];
int comp(int x,int y,int pos) { return s[x]+(pos-)*p[x]>s[y]+(pos-)*p[y];}
double getans(int x,int pos){ return s[x]+(pos-)*p[x]; }
void update(int Now,int L,int R,int x)
{
int Mid=(L+R)>>;
if(L==R){ if(comp(x,Mx[Now],Mid)) Mx[Now]=x; return ; }
if(comp(x,Mx[Now],Mid)){ //只针对着两条线段比较
if(comp(Mx[Now],x,L)) update(Now<<,L,Mid,Mx[Now]); //任然是比较这两条线段?
if(comp(Mx[Now],x,R)) update(Now<<|,Mid+,R,Mx[Now]);
Mx[Now]=x;
}
else {
if(comp(x,Mx[Now],L)) update(Now<<,L,Mid,x);
if(comp(x,Mx[Now],R)) update(Now<<|,Mid+,R,x);
}
}
double query(int Now,int L,int R,int pos)
{
if(L==R) return getans(Mx[Now],pos);
int Mid=(L+R)>>; double ans=getans(Mx[Now],pos);
if(pos<=Mid) return max(ans,query(Now<<,L,Mid,pos));
else return max(ans,query(Now<<|,Mid+,R,pos));
}
int main()
{
int N; scanf("%d",&N);
while(N--){
char c[]; scanf("%s",c);
if(c[]=='P'){
cnt++; scanf("%lf%lf",&s[cnt],&p[cnt]);
update(,,M,cnt);
}
else {
int x; scanf("%d",&x);
double ans=query(,,M,x);
printf("%d\n",(int)ans/);
}
}
return ;
}
BZOJ-1568: Blue Mary开公司 (李超线段树)的更多相关文章
- 【BZOJ-1568】Blue Mary开公司 李超线段树 (标记永久化)
1568: [JSOI2008]Blue Mary开公司 Time Limit: 15 Sec Memory Limit: 162 MBSubmit: 557 Solved: 192[Submit ...
- JSOI2008 Blue Mary开公司 | 李超线段树学习笔记
题目链接:戳我 这相当于是一个李超线段树的模板qwqwq,题解就不多说了. 代码如下: #include<iostream> #include<cstdio> #include ...
- [bzoj1568][JSOI2008]Blue Mary开公司——李超线段树
题目大意 题解 这道题需要用到一种叫做李超线段树的东西.我对于李超线段树,是这样理解的: 给节点打下的标记不进行下传,而是仅仅在需要的时候进行下传,这就是所谓永久化标记. 对于这道题,借用一张图, 这 ...
- BZOJ.1568.[JSOI2008]Blue Mary开公司(李超线段树)
题目链接 线段树每个节点记录\(f(mid)\)最大的直线(在\(mid\)处函数值最大的直线),称作优势线段(还是直线啊...无所谓了). 如果是在区间插入线段会影响\(O(\log n)\)个区间 ...
- [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 ...
- P4254 [JSOI2008]Blue Mary开公司 (李超树)
题意:插入一些一次函数线段 每次询问在x = x0处这些线段的最大值 题解:李超树模版题 维护优势线段 注意这题的输入是x=1时的b #include <iostream> #includ ...
- Luogu 4254 [JSOI2008]Blue Mary开公司
BZOJ 1568 学习了一波李超线段树. 大佬blog 这个东西专门用来维护插入一条线段和区间/单点的最大/最小值. 插入的时候讨论: 1.如果当前结点上没有线段,那么直接插入. 2.如果当前结点上 ...
随机推荐
- ReactiveCocoa入门教程——第二部分【转载】
ReactiveCocoa是一个框架,它能让你在iOS应用中使用函数响应式编程(FRP)技术.在本系列教程的第一部分中,你学到了如何将标准的动作与事件处理逻辑替换为发送事件流的信号.你还学到了如何转换 ...
- Rate Monotonic Scheduling algorithm
这篇文章写得不错 http://barrgroup.com/embedded-systems/How-To/RMA-Rate-Monotonic-Algorithm 另外rtems的官方文档也有类似说 ...
- python升级或者其他原因把yum搞坏了
第一个命令查询出来,原本是安装的啥版本 rpm -qa | grep python- | grep 2.6 然后执行下一个命令,就可以安装原本的python版本了,注意链接要换成你对应的那个版本 rp ...
- 有一个数组a[N]顺序存放0~N-1,要求每隔两个数删掉一个数,到末尾时循环至开头继续进行,求最后一个被删掉的数的原始下标位置。以8个数(N=7)为例:{0,1,2,3,4,5,6,7},0->1->2(删除)->3->4->5(删除)->6->7->0(删除),如此循环直到最后一个数被删除。
// ConsoleApplication12.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" // ConsoleApplication1 ...
- JavaScript中setInterval用法
setInterval动作的作用是在播放动画的时,每隔一定时间就调用函数,方法或对象.可以使用本动作更新来自数据库的变量或更新时间显示. setInterval动作的语法格式如下:setInterva ...
- Jquery 常用方法总结
1.Attribute(属性): $(”p”).addClass(css中定义的样式类型); 给某个元素添加样式 $(”img”).attr({src:”test.jpg”,alt:”test Ima ...
- KEIL下分散加载文件的使用(zt)
KEIL下分散加载文件的使用 对于分散加载的概念,在<ARM体系结构与编程>书中第11章有明确介绍. 分散加载文件(即scatter file 后缀为.scf)是一个文本文件,通过编写 ...
- 3597: [Scoi2014]方伯伯运椰子[分数规划]
3597: [Scoi2014]方伯伯运椰子 Time Limit: 30 Sec Memory Limit: 64 MB Submit: 404 Solved: 249 [Submit][Sta ...
- 九度OJ 1165:字符串匹配 (模式匹配)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:3219 解决:1149 题目描述: 读入数据string[ ],然后读入一个短字符串.要求查找string[ ]中和短字符串的所有匹配,输出 ...
- UIWebview加载H5界面侧滑返回上一级
一.UIWebview的发现 问题发现:当UIWebview王深层次点击的时候,返回时需要webView执行goBack方法一级一级返回,这样看到的webView只是在该界面执行刷新,并看不到类似iO ...