[JSOI2008]Blue Mary开公司

lc线段树入门题

访问O\((log 2n)\)

查询O(\(log n\))

考虑斜率维护凸包(单调)

标记永久化

简单来说就是做好以下几件事

  • 在[l,r]区间内获得最大平均函数值(mid)
  • 针对斜率不同,将失败线传送至交点较高部分,修改下传
  • 暴力修改,访问至根节点
#include<bits/stdc++.h>
#define re return
#define D double
#define lson rt<<1
#define rson rt<<1|1
#define inc(i,l,r) for(int i=l;i<=r;++i)
const int maxn=100005;

using namespace std;
template<typename T>inline void rd(T&x)
{
	char c;bool f=0;
	while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
	x=c^48;
	while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
	if(f)x=-x;
}

int n;
struct node
{
	double k,b;
}tree[maxn<<2];
inline D f(D k,D b,int x){re (x-1)*k+b;}
inline void add(int rt,int l,int r,D k,D b)
{
	if(l==r)
	{
		if(f(tree[rt].k,tree[rt].b,l)<f(k,b,l))
			tree[rt]=(node){k,b};
			re ;
	}
	int mid=(l+r)>>1;
	if(k<tree[rt].k)
	{
		if(f(tree[rt].k,tree[rt].b,mid)<f(k,b,mid))
		{
			add(rson,mid+1,r,tree[rt].k,tree[rt].b);
			tree[rt]=(node){k,b};
		}
		else add(lson,l,mid,k,b);
	}
	else 
	{
		if(f(tree[rt].k,tree[rt].b,mid)<f(k,b,mid))
		{
			add(lson,l,mid,tree[rt].k,tree[rt].b);
			tree[rt]=(node){k,b};
		}
		else add(rson,mid+1,r,k,b);
	}
}

inline D query(int rt,int l,int r,int x)
{
	if(l==r) re f(tree[rt].k,tree[rt].b,x);
	int mid=(l+r)>>1;
	if(mid>=x)re max(f(tree[rt].k,tree[rt].b,x),query(lson,l,mid,x));
		else  re max(f(tree[rt].k,tree[rt].b,x),query(rson,mid+1,r,x));
}
int main()
{
	D kk,bb;int x;
	char s[20];
	freopen("in.txt","r",stdin);
	scanf("%d",&n);
	inc(i,1,n)
	{
		scanf("%s",s);
		if(s[0]=='P')
		{
			scanf("%lf%lf",&bb,&kk);
			add(1,1,50005,kk,bb);
		}
		else 
		{
			scanf("%d",&x);
			D ans=query(1,1,50005,x);
			printf("%d\n",(int)(ans/100));
		}
	}
	re 0;
}
posted @ 2019-07-29 18:48  凉如水  阅读(126)  评论(0编辑  收藏  举报