您的位置:首页 > 产品设计 > UI/UE

【JSOI2008】Blue Mary开公司 李超线段树

2017-08-12 16:17 246 查看


F.A.QsHomeDiscussProblemSetStatusRanklistContest入门OJLoginRegister捐赠本站
Notice:为保证OJ试题质量,今后添加的试题如有发现出现重复,请联系我们删除,谢谢!

Problem 1568. – [JSOI2008]Blue Mary开公司

1568: [JSOI2008]Blue Mary开公司

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


[Submit][Status][Discuss]

HOME
Back

한국어
中文
فارسی
English
ไทย

版权所有 ©2008-2012 大视野在线测评 | 湘ICP备13009380号 |

<div>Based on opensource project <a href="http://hustoj.googlecode.com">hustoj</a>.</div>
</div>


题解:李超线段树,超哥线段树一般可以处理一些区间线段的题目,可以维护线段或直线。

上个图,原图出自网络,侵删。



其实就是维护某个区间的答案,每个区间的答案就是该区间最长的那条线段的答案,有交点的部分怎么办?因为查询的时候是递归到叶子结点更新答案,所以所有应该遍历到的线段都会被遍历到。

更新答案的时候注意判断的方式,通过存储斜率k和截距b来实现。

这道题注意作弊范围和精度。

代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#define MAXN 100005
using namespace std;
struct node
{
double k,b;
}tree[MAXN*8];
int n;
double min(double x,double y)
{
if (x<y) return x;
return y;
}
void update(int root,int l,int r,double k,double b)
{
if (!tree[root].b&&!tree[root].k)
{
tree[root].b=b;tree[root].k=k;
return ;
}
int mid=(l+r)>>1;
double x=(mid-1.0)*tree[root].k+tree[root].b;
double y=(mid-1.0)*k+b;
if (l==r)
{
if (y>x) tree[root].k=k,tree[root].b=b;
return;
}
if (tree[root].k>=k&&tree[root].b>b)
return ;

if (k>=tree[root].k&&b>tree[root].b)
{
tree[root].k=k;tree[root].b=b;
return ;
}
if (tree[root].k*(l-1)+tree[root].b>k*(l-1)+b&&tree[root].k>k) return ;
else if (tree[root].k>k)
{
if (x>=y)
update(root*2,l,mid,k,b);
else
{
update(root*2+1,mid+1,r,tree[root].k,tree[root].b);
tree[root].k=k;tree[root].b=b;
}
}
else
{
if (x>=y)
update(root*2+1,mid+1,r,k,b);
else
{
update(root*2,l,mid,tree[root].k,tree[root].b);
tree[root].k=k;
tree[root].b=b;
}
}
}
double query(int root,int l,int r,int x)
{
int mid=(l+r)>>1;double tmp=0;
tmp=max(tmp,(x-1.0)*tree[root].k+tree[root].b);
if (l==r) return tmp;
if (x<=mid) tmp=max(tmp,query(root*2,l,mid,x));
else if (x>mid) tmp=max(tmp,query(root*2+1,mid+1,r,x));
return tmp;
}
int main()
{
char c[100];
int x;double k,b;
scanf("%d",&n);
for (int i=1;i<=n;i++)
{
scanf("%s",c);
if (c[0]=='Q')
{
scanf("%d",&x);
double ans=0;
ans=query(1,1,50000,x);
ans=floor(ans/100);
printf("%.0lf\n",ans);
}
else if (c[0]=='P')
{
scanf("%lf%lf",&b,&k);
update(1,1,50000,k,b);

}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: