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

1568: [JSOI2008]Blue Mary开公司

Time Limit: 15 Sec  Memory Limit: 162 MB
Submit: 1080  Solved: 379
[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

HINT

Source

超哥线段树的模板题。

超哥线段树是处理一次函数的一种线段树,

在超哥线段树中,每一个节点保存着一个一次函数所对应的编号,

那他是怎么保存的呢?

借用一位大神的图片

没错就是这样,

然后对于每一次插入操作,

我们去递归当前 值小的节点 的值 可能比 值大的节点 的 值 大的方向。。。。。。。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<bitset>
#define ls k<<1
#define rs k<<1|1
using namespace std;
const int MAXN=1000001;
inline void read(int &n)
{
	char c=‘+‘;int x=0;bool flag=0;
	while(c<‘0‘||c>‘9‘){c=getchar();if(c==‘-‘)flag=1;}
	while(c>=‘0‘&&c<=‘9‘){x=x*10+(c-48);c=getchar();}
	n=flag==1?-x:x;
}
struct funtion
{
	double k,b;
}a[MAXN];// 记录每一条线段
int tree[MAXN];// 每一个节点所对应线段的编号
int tot=0;// 总的线段数量
inline int pd(int now,int will,int day)
{
	--day;
	return a[now].k*day+a[now].b>a[will].k*day+a[will].b;
}
inline void insert(int k,int l,int r,int now)
{
	if(l==r)
	{
		if(pd(now,tree[k],l))	tree[k]=now;
		return ;
	}
	int mid=(l+r)>>1;
	if(a[now].k>a[tree[k]].k)// 当前点的斜率比目标点的斜率大
	{
		if(pd(now,tree[k],mid))	insert(ls,l,mid,tree[k]),tree[k]=now;
		else	insert(rs,mid+1,r,now);
	}
	else
	{
		if(pd(now,tree[k],mid))	insert(rs,mid+1,r,tree[k]),tree[k]=now;
		else	insert(ls,l,mid,now);
	}
}
double ans=0;
void query(int k,int l,int r,int now)
{
	ans=max(ans,a[tree[k]].k*(now-1)+a[tree[k]].b);
	if(l==r)	return ;
	int mid=(l+r)>>1;
	if(now<=mid)	query(ls,l,mid,now);
	else 	query(rs,mid+1,r,now);
}
int main()
{
	ios::sync_with_stdio(0);
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		string opt;
		cin>>opt;
		if(opt[0]==‘P‘)
		{
			++tot;
			cin>>a[tot].b>>a[tot].k;
			insert(1,1,n,tot);
		}
		else if(opt[0]==‘Q‘)
		{
			int p;
			cin>>p;
			ans=0;
			query(1,1,n,p);
			printf("%d\n",(int)(ans/100));
		}
	}
	return 0;
}

  

时间: 2024-08-15 05:38:20

BZOJ 1568: [JSOI2008]Blue Mary开公司(超哥线段树)的相关文章

数据结构(线段树):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,则

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

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

bzoj1568 [JSOI2008]Blue Mary开公司

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

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

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

[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

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

【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,则后