BZOJ 1568: [JSOI2008]Blue Mary开公司

超哥线段树

#include<cstdio>
#include<algorithm>
using namespace std;
const int lim=50000;
double ans;
char s[15];
struct node{
	double k,b;
}Line[2000005];
inline double check(node a,node b){
	return (a.b-b.b)/(b.k-a.k);
}
inline double calc(double x,node line){
	return line.k*x+line.b;
}
inline void update(int t,node line){
	Line[t]=line;
}
inline void insert(int t,int l,int r,int x,int y,node line){
	if (l>y || r<x) return;
	if (l>=x && r<=y){
		double Lmax=calc(l,line),Rmax=calc(r,line);
		double Lt=calc(l,Line[t]),Rt=calc(r,Line[t]);
		if (Lmax<=Lt && Rmax<=Rt) return;
		else if (Lmax>Lt && Rmax>Rt) update(t,line);
		else{
			int mid=(l+r)>>1;
			double Key=check(line,Line[t]);
			node To=line;
			if (Key<=mid) {
				if (Lmax<Lt) {
					To=Line[t];
					update(t,line);
				}
				insert(t<<1,l,mid,x,y,To);
			}
			else {
				if (Rmax<Rt){
					To=Line[t];
					update(t,line);
				}
				insert(t<<1|1,mid+1,r,x,y,To);
			}
		}
		return;
	}
	int mid=(l+r)>>1;
	insert(t<<1,l,mid,x,y,line);
	insert(t<<1|1,mid+1,r,x,y,line);
}
void query(int t,int l,int r,int key){
	double Key=calc(key,Line[t]);
	if (Key>ans) ans=Key;
	if (l==r) return;
	int mid=(l+r)>>1;
	if (key<=mid) query(t<<1,l,mid,key);
	else query(t<<1|1,mid+1,r,key);
}
int main(){
	int q;
	scanf("%d",&q);
	while (q--){
		scanf("%s",s);
		if (s[0]=='Q'){
			int X;
			scanf("%d",&X);
			ans=0;
			query(1,1,lim,X);
			printf("%d\n",(int)(ans/100));
		}
		else{
			double B,K;
			scanf("%lf%lf",&B,&K);
			B-=K;
			insert(1,1,lim,1,lim,(node){K,B});
		}
	}
	return 0;
}

  

 

posted @ 2018-10-24 11:18  ~Silent  阅读(118)  评论(0编辑  收藏  举报
Live2D