# 李超线段树入门

## 算法总概

### 大致思路:

1. 若当前区间没有直线,加入当前直线即可
2. "区间直线"整体在"插入直线"下,整体替换
3. "插入直线"整体在"区间直线"下,不做更改
4. 两直线有交点则判断交点的位置,并下放插入直线到左右儿子

## code

#include<bits/stdc++.h>
using namespace std;
#define re register
#define ll long long
#define get getchar()
#define in inline
#define db double
const int _=2e5+234;
int n;
char ch[101];
struct LCXDtree{
db b, k;
int fl;
}a[_<<2];
#define ls k<<1
#define rs k<<1|1
in void insert(int k,int l,int r,db K,db B)
{
if(l>r) return;
if(!a[k].fl){ a[k].fl=1; a[k].k=K, a[k].b=B; return;}
int l1=a[k].k*(l-1)+a[k].b, l2=K*(l-1)+B, r1=a[k].k*(r-1)+a[k].b, r2=K*(r-1)+B;
if(l1>=l2 && r1>=r2) return;
if(l1<l2 && r1<r2){ a[k].k=K, a[k].b=B; return;}
int mid=l+r>>1, mid1=a[k].k*(mid-1)+a[k].b, mid2=K*(mid-1)+B;
if(l1<l2)
{
insert(ls,l,mid,K,B);
if(mid1<mid2) insert(rs,mid+1,r,K,B);
}
else
{
insert(rs,mid+1,r,K,B);
if(mid1<mid2) insert(ls,l,mid,K,B);
}
}
in db query(int k,int l,int r,int x)
{
if(l==r) return a[k].k*(l-1)+a[k].b;
int mid=l+r>>1; db w=a[k].k*(x-1)+a[k].b;
if(x<=mid) return max(w,query(ls,l,mid,x));
else return max(w,query(rs,mid+1,r,x));
}
int main()
{
int T; cin>>T; n=50000;
while(T--)
{
cin>>ch+1;
if(ch[1]=='P')
{
db x,y; scanf("%lf%lf",&x,&y);
insert(1,1,n,y,x);
}
else
{
int x; scanf("%d", &x);
printf("%d\n", int(query(1,1,n,x))/100);
}
}
return 0;
}


posted @ 2021-09-12 22:03  yzhx  阅读(26)  评论(0编辑  收藏  举报