1568: [JSOI2008]Blue Mary开公司

1568: [JSOI2008]Blue Mary开公司

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

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

约定: 1 <= N <= 100000 1 <= T <=50000 0 < P < 100,| S | <= 10^6 提示:本题读写数据量可能相当巨大,请选手注意选择高效的文件读写方式。

Source

[ Submit][ Status][ Discuss]

据说这是个叫李超树的东西
维护一个线段树
每个点维护一条线段的信息
考虑插入一条线段:
新线段在[L,R]处处都比老线段优--替换之
新线段在[L,R]处处都比老线段差--舍弃新线段
如果以上都不满足,将新线段断成两段,舍弃一段(劣的)插入一段(优的)
注意插入的时候只能往一个地方走(详见代码)


注意询问的时候那个日期要-1。。。
嗯,,输出的时候用int强转吧,别偷懒(WA惨了)
#include<iostream>
#include<cstdio>
#include<queue>
#include<vector>
#include<bitset>
#include<algorithm>
#include<cstring>
#include<map>
#include<stack>
#include<set>
#include<cmath>
#include<ext/pb_ds/priority_queue.hpp>
using namespace std;

const int maxn = 5E4 + 10;
typedef double DB;

DB k[maxn*20],b[maxn*20];
int n;
char com[20];

void Insert(int o,int l,int r,DB K,DB B)
{
	DB A1 = K*(DB)(l) + B,A2 = k[o]*(DB)(l) + b[o];
	DB B1 = K*(DB)(r) + B,B2 = k[o]*(DB)(r) + b[o];
	if (A1 > A2 && B1 > B2) {k[o] = K; b[o] = B; return;}
	if (A1 < A2 && B1 < B2) return;
	if (l == r) return;
	DB x = (b[o] - B)/(K - k[o]);
	int mid = (l + r) >> 1;
	if (x <= mid) {
		if (A1 > A2) Insert(2*o,l,mid,K,B);
		else Insert(2*o,l,mid,k[o],b[o]),k[o] = K,b[o] = B;
	}
	else {
		if (A1 > A2) Insert(2*o+1,mid+1,r,k[o],b[o]),k[o] = K,b[o] = B;
		else Insert(2*o+1,mid+1,r,K,B); 
	}
}

DB Query(int o,int l,int r,int pos)
{
	DB ret = k[o]*(DB)(pos) + b[o];
	if (l == r) return ret;
	int mid = (l + r) >> 1;
	if (pos <= mid) ret = max(ret,Query(2*o,l,mid,pos));
	else ret = max(ret,Query(2*o+1,mid+1,r,pos));
	return ret;
}

int main()
{
	#ifdef DMC
		freopen("Corporation2.in","r",stdin);
	#endif
	
	cin >> n;
	while (n--) {
		scanf("%s",com);
		if (com[0] == 'P') {
			DB K,B; scanf("%lf%lf",&B,&K);
			Insert(1,0,maxn,K,B);
		}
		else {
			int x; scanf("%d",&x); --x;
			DB ans = Query(1,1,maxn,x);
			ans /= 100.00; int Ans = ans;
			printf("%d\n",Ans);
		}
	}
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值