BZOJ 1568: [JSOI2008]Blue Mary开公司 (李超线段树)

第一次学这个东西,感觉还是挺好写 + 好用的. 

code: 

#include <bits/stdc++.h>    
#define ll long long 
#define M 50000   
#define N 100008
#define eps 1e-12      
#define lson now<<1  
#define rson now<<1|1      
#define comp(a,b) ((a-b)>eps)     

using namespace std;  

void setIO(string s) 
{
    string in=s+".in"; 
    string out=s+".out"; 
    freopen(in.c_str(),"r",stdin); 
    freopen(out.c_str(),"w",stdout);  
}

// y=kx+b   
struct Line 
{   
    double k,b;    
    int l,r,flag;    
    Line(int a1=0,int b1=0,double c1=0,double d1=0):l(a1),r(b1),k(c1),b(d1){} 
    double calc(int pos) { return k*pos+b; }      
    double cross(Line t) { return (b-t.b)/(t.k-k); }     
}s[N<<2];  

int n;    

void build(int l,int r,int now) 
{     
    s[now].k=s[now].b=0;     
    s[now].l=1,s[now].r=M,s[now].flag=-1;           
    if(l==r) return;    
    int mid=(l+r)>>1;   
    build(l,mid,lson),build(mid+1,r,rson);  
}    

void update(int l,int r,int now,Line k) 
{  
    if(l>=k.l&&r<=k.r) 
    { 
        if(k.calc(l)-s[now].calc(l)>eps&&k.calc(r)-s[now].calc(r)>eps)    
            s[now]=k;    
        else if(k.calc(l)-s[now].calc(l)>eps||k.calc(r)-s[now].calc(r)>eps)  
        {
            int mid=(l+r)>>1;     
            if(k.calc(mid)-s[now].calc(mid)>eps) 
            {
                Line tmp=k;  
                k=s[now],s[now]=tmp;    
            }
            if(k.cross(s[now])-mid<-eps) 
                update(l,mid,lson,k);    
            else update(mid+1,r,rson,k);    
        }
        return; 
    }
    int mid=(l+r)>>1;   
    if(k.l<=mid)  update(l,mid,lson,k);     
    if(k.r>mid)   update(mid+1,r,rson,k);   
}

double query(int l,int r,int now,int p) 
{
    if(l==r) return s[now].calc(p);   
    int mid=(l+r)>>1;   
    double ans=s[now].calc(p);   
    if(p<=mid) ans=max(ans,query(l,mid,lson,p));  
    else ans=max(ans,query(mid+1,r,rson,p));   
    return ans;  
}

int main() 
{ 
    // setIO("input");    
    scanf("%d",&n);   
    build(1,M,1);      
    for(int i=1;i<=n;++i) 
    {
        char op[10];   
        scanf("%s",op);  
        if(op[0]=='P') 
        {   
            double s,p;  
            scanf("%lf%lf",&s,&p);    
            Line now=Line(1,M,p,s-p); 
            update(1,M,1,now);   
        } 
        else
        {   
            int x;  
            scanf("%d",&x);    
            int ans=(int)floor(query(1,M,1,x)/100);      
            printf("%d\n",ans);   
        }
    }
    return 0;  
}

  

posted @ 2020-05-11 00:04  EM-LGH  阅读(120)  评论(0编辑  收藏  举报