[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;
}