bzoj3938 Robot (Li Chao line segment tree + discretization)

Water inscription year series.
The function of each robot's position over time should be a piecewise function, with each segment being a primary function.
We can go offline and discretize the time, which is to maintain the maximum value of several line segments.
You can insert them all first, and then deal with the query last.
It can be solved by using Li Chao line segment tree. Maintain the maximum and minimum values ​​separately.
the complexity O ( n l og2n)

#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 nn,n,lst[N],Q[N*5],aa[N*6],m,n1,n2,now[N];
char s[N];
struct Line{
    ll k,b;
    ll f(ll x){return k*x+b;}
}a[N*3];
struct oper{
    int tim,x,k;
}O[N];
struct node{
    int x,y;
}tr[N*6*4];
inline void ins(int p,int l,int r,int x,int y,int id){//最大值
    if(x<=l&&r<=y){
        if(!tr[p].x){tr[p].x=id;return;}
        ll fl=a[tr[p].x].f(aa[l])-a[id].f(aa[l]),fr=a[tr[p].x].f(aa[r])-a[id].f(aa[r]);
        if(fl>=0&&fr>=0) return;
        if(fl<0&&fr<0){tr[p].x=id;return;}int mid=l+r>>1;
        if(fl>0){
            if(a[tr[p].x].f(aa[mid])>a[id].f(aa[mid])) ins(p<<1|1,mid+1,r,x,y,id);
            else ins(p<<1,l,mid,x,y,tr[p].x),tr[p].x=id;
        }else{
            if(a[tr[p].x].f(aa[mid])>a[id].f(aa[mid])) ins(p<<1,l,mid,x,y,id);
            else ins(p<<1|1,mid+1,r,x,y,tr[p].x),tr[p].x=id;
        }return;
    }int mid=l+r>>1;
    if(x<=mid) ins(p<<1,l,mid,x,y,id);
    if(y>mid) ins(p<<1|1,mid+1,r,x,y,id);
}
inline void ins1(int p,int l,int r,int x,int y,int id){//最小值
    if(x<=l&&r<=y){
        if(!tr[p].y){tr[p].y=id;return;}
        ll fl=a[tr[p].y].f(aa[l])-a[id].f(aa[l]),fr=a[tr[p].y].f(aa[r])-a[id].f(aa[r]);
        if(fl<=0&&fr<=0) return;
        if(fl>0&&fr>0){tr[p].y=id;return;}int mid=l+r>>1;
        if(fl>0){
            if(a[tr[p].y].f(aa[mid])<a[id].f(aa[mid])) ins1(p<<1,l,mid,x,y,id);
            else ins1(p<<1|1,mid+1,r,x,y,tr[p].y),tr[p].y=id;
        }else{
            if(a[tr[p].y].f(aa[mid])<a[id].f(aa[mid])) ins1(p<<1|1,mid+1,r,x,y,id);
            else ins1(p<<1,l,mid,x,y,tr[p].y),tr[p].y=id;
        }return;
    }int mid=l+r>>1;
    if(x<=mid) ins1(p<<1,l,mid,x,y,id);
    if(y>mid) ins1(p<<1|1,mid+1,r,x,y,id);
}
inline ll askmn(int p,int l,int r,int x){
    if(l==r) return a[tr[p].y].f(aa[x]);
    int mid=l+r>>1;
    if(x<=mid) return min(askmn(p<<1,l,mid,x),a[tr[p].y].f(aa[x]));
    return min(askmn(p<<1|1,mid+1,r,x),a[tr[p].y].f(aa[x]));
}
inline ll askmx(int p,int l,int r,int x){
    if(l==r) return a[tr[p].x].f(aa[x]);
    int mid=l+r>>1;
    if(x<=mid) return max(askmx(p<<1,l,mid,x),a[tr[p].x].f(aa[x]));
    return max(askmx(p<<1|1,mid+1,r,x),a[tr[p].x].f(aa[x]));
}
int main(){
//  freopen("a.in","r",stdin);
    nn=read();m=read();
    for(int i=1;i<=nn;++i) a[i].b=read(),now[i]=i;
    for(int i=1;i<=m;++i){
        aa[i]=read();scanf("%s",s+1);
        if(s[1]=='c') O[++n1].tim=aa[i],O[n1].x=read(),O[n1].k=read();
        else Q[++n2]=aa[i];
    }aa[++m]=0;sort(aa+1,aa+m+1);n=unique(aa+1,aa+m+1)-aa-1;m=nn;
    for(int i=1;i<=n1;++i){
        int x=O[i].x,l=lower_bound(aa+1,aa+n+1,lst[x])-aa,r=lower_bound(aa+1,aa+n+1,O[i].tim)-aa;
        ins(1,1,n,l,r,now[x]);ins1(1,1,n,l,r,now[x]);
        a[++m].k=O[i].k;a[m].b=a[now[x]].b+O[i].tim*(a[now[x]].k-a[m].k);
        now[x]=m;lst[x]=O[i].tim;
    }for(int i=1;i<=nn;++i){
        int l=lower_bound(aa+1,aa+n+1,lst[i])-aa;
        ins(1,1,n,l,n,now[i]);ins1(1,1,n,l,n,now[i]);
    }for(int i=1;i<=n2;++i){
        int x=lower_bound(aa+1,aa+n+1,Q[i])-aa;
        ll ans=max(-askmn(1,1,n,x),askmx(1,1,n,x));
        printf("%lld\n",ans);
    }return 0;
}

Guess you like

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