bzoj1568 [JSOI2008] Blue Mary opened a company (Li Chao line segment tree)

The Li super line segment tree is used to maintain the maximum value of several primary functions at a certain point.
i.e. maintain a bunch of lines/segments.
We use the idea of ​​permanent marking, and each node records the most dominant line segment in this interval (that is, the line segment with the most exposure in this interval).
We consider how to maintain a new line.
If there is no most dominant line segment in this interval, then cover it directly.
If the most dominant line segment of this interval is completely higher than the new line segment, then return directly.
If the most dominant line segment of this interval is completely lower than the new line segment, it is directly overwritten.
If there is an intersection point, calculate the intersection point, the most exposed line segment is the most dominant line segment, and then another line segment is lowered to the son of the intersection point.
A line segment covers at most logn intervals, and each interval has at most logn layers, so the complexity is O ( n l og2n)
When querying, you can directly take the max of the most dominant line segment of the interval covering x on the line segment tree.
For this problem, because it is a straight line, the complexity should be O ( n l o gn)

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
#define N 100010
inline int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    return x*f;
}
int owo,m=0,n=50000;
char op[N];
struct Line{
    double k,b;
    double f(int x){return k*x+b;}
}a[N];
struct node{
    int x;
}tr[N<<1];
inline void ins(int p,int l,int r,int x){
    if(l==r){if(!tr[p].x||a[tr[p].x].f(l)<a[x].f(l)) tr[p].x=x;return;}
    int mid=l+r>>1;
    if(!tr[p].x){tr[p].x=x;return;}
    if(a[tr[p].x].k<a[x].k){
        if(a[tr[p].x].f(mid)<a[x].f(mid)) ins(p<<1,l,mid,tr[p].x),tr[p].x=x;
        else ins(p<<1|1,mid+1,r,x);
    }else{
        if(a[tr[p].x].f(mid)<a[x].f(mid)) ins(p<<1|1,mid+1,r,tr[p].x),tr[p].x=x;
        else ins(p<<1,l,mid,x);
    }
}
inline double ask(int p,int l,int r,int x){
    if(l==r) return a[tr[p].x].f(x);
    int mid=l+r>>1;
    if(x<=mid) return max(a[tr[p].x].f(x),ask(p<<1,l,mid,x));
    return max(a[tr[p].x].f(x),ask(p<<1|1,mid+1,r,x));
}
int main(){
//  freopen("a.in","r",stdin);
    owo=read();
    while(owo--){
        scanf("%s",op+1);
        if(op[1]=='P'){
            ++m;scanf("%lf%lf",&a[m].b,&a[m].k);a[m].b-=a[m].k;
            ins(1,1,n,m);
        }else{
            printf("%d\n",(int)(ask(1,1,n,read())/100));
        }
    }return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325737650&siteId=291194637