Lie Tree - drawn by the primary remember the accident simulation game NOIP

What Lie tree?

Li Chao tree is a tree line with a way to maintain a straight line, as is the training team players Li Chao said in the paper, it is known as the Lie tree.

This is a kind of NOIP simulation game?

It's about timeThe test of life and death.
So I am very seriously.
So the first question:
Here Insert Picture Description
I suddenly thought of Li Chao tree, just put it straight into a parabolic thing -
so I started. .
Since the first time I played Li Chao tree, a little embarrassed.
1 hour transfer to sample ..
3 hours filming ...
and then very embarrassing discovery limit data I ran 23 seconds! ! !
Mentality did not ...
do not want to play the match ...

4000 + program, perhaps only violence points ...

I found it very embarrassing to go 90 points ...

code show as below

(Bloggers lazy, did not play simple Lie tree)
code is ugly, the situation is a lot of
attitude is very collapse

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#define LL long long
using namespace std;

const LL maxn=5*1e5+10;
const LL maxq=5*1e5+10;
const LL maxX=32323+10;
const LL XXX=-32324-100;

struct root{double x,x1;};
struct Moon{
    LL a,b;
}f[2*maxX*4];

LL a[maxn],b[maxn];
LL x[maxq];
LL minx,maxx;
LL N,Q;

inline LL read(){
    LL d=0,f=1;char s=getchar();
    while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();}
    return d*f;
}

root cro(LL a1,LL b1,LL a2,LL b2,LL liml,LL limr){
    LL a=a1-a2,b=b1-b2;
    root R;
    if(a==0){
        R.x=0;
        R.x1=XXX;
        if(R.x>limr||R.x<liml) R.x=XXX;
    }else{
        LL delta=b*b;
        if(delta==0){
            R.x=(-b+sqrt(delta+0.0)+0.0)/(2*a+0.0);
            R.x1=XXX;
            if(R.x>limr||R.x<liml) R.x=XXX;
        }else{
            double R1=(-b+sqrt(delta+0.0)+0.0)/(2*a+0.0);
            double R2=(-b-sqrt(delta+0.0)+0.0)/(2*a+0.0);
            if(R1>R2) swap(R1,R2);
            R.x=R1,R.x1=R2;
            while(R.x!=XXX&&(R.x>=limr||R.x<=liml)) 
                R.x=R.x1,R.x1=XXX;
        }
    }
    return R;
}

LL val(LL a,LL b,LL x){
    return a*x*x+b*x;
}


void add(LL v,LL l,LL r,LL a,LL b,LL L,LL R){
    if(f[v].a<XXX){
        f[v].a=a,f[v].b=b;
        return;
    }
    if(f[v].a==a&&f[v].b==b) return;
    root p=cro(a,b,f[v].a,f[v].b,l,r);
    if(p.x==XXX){
        int ll=l;
        while(ll<r&&val(a,b,ll)==val(f[v].a,f[v].b,ll)) ++ll;
        if(val(a,b,ll)>val(f[v].a,f[v].b,ll)) f[v].a=a,f[v].b=b;
        return;
    }else{
        LL nl,nr;
        if(p.x1==XXX){
            //交点只有一个 
            
            int ll=l;
            while(ll<r&&val(a,b,ll)==val(f[v].a,f[v].b,ll)) ++ll;
            if(val(a,b,ll)>val(f[v].a,f[v].b,ll))
                nl=l,nr=floor(p.x);
            else nl=ceil(p.x),nr=r;
            ll=r;
            while(ll>l&&val(a,b,ll)==val(f[v].a,f[v].b,ll)) --ll;
            if(val(a,b,ll)>val(f[v].a,f[v].b,ll)&&nl==l&&nr==floor(p.x)){
                f[v].a=a,f[v].b=b;
                return;
            }
            if(val(a,b,ll)<val(f[v].a,f[v].b,ll)&&nl==ceil(p.x)&&nr==r) return;
            int mid=((l+r)%2!=0)?(l+r-1)/2:(l+r)/2;
            if(nr<=mid) add(v*2,l,mid,a,b,nl,nr);
            else if(nl>mid) add(v*2+1,mid+1,r,a,b,nl,nr);
            else{
                add(v*2,l,mid,a,b,nl,mid);
                add(v*2+1,mid+1,r,a,b,mid+1,nr);    
            }
        }else{
            bool flag=0;
            nl=ceil(p.x),nr=floor(p.x1);
            int ll=nl;
            while(ll<nr&&val(a,b,ll)==val(f[v].a,f[v].b,ll)) ++ll;
            if(val(a,b,ll)==val(f[v].a,f[v].b,ll)){
                ll=nl;
                while(ll>l&&val(a,b,ll)==val(f[v].a,f[v].b,ll)) --ll;
                if(val(a,b,ll)==val(f[v].a,f[v].b,ll)){
                    ll=nr;
                    while(ll<r&&val(a,b,ll)==val(f[v].a,f[v].b,ll)) ++ll;
                }
                if(val(a,b,ll)>val(f[v].a,f[v].b,ll)) flag=1;
            }else if(val(a,b,ll)<val(f[v].a,f[v].b,ll)) flag=1;
            if(flag){
                // two side
                int nl1,nr1;
                nl1=l,nr1=nl-1;
                int mid=((l+r)%2!=0)?(l+r-1)/2:(l+r)/2;
                if(nr1<=mid) add(v*2,l,mid,a,b,nl1,nr1);
                else if(nl1>mid) add(v*2+1,mid+1,r,a,b,nl1,nr1);
                else{
                    add(v*2,l,mid,a,b,nl1,mid);
                    add(v*2+1,mid+1,r,a,b,mid+1,nr1);   
                }
                nl1=nr+1,nr1=r;
                mid=((l+r)%2!=0)?(l+r-1)/2:(l+r)/2;
                if(nr1<=mid) add(v*2,l,mid,a,b,nl1,nr1);
                else if(nl1>mid) add(v*2+1,mid+1,r,a,b,nl1,nr1);
                else{
                    add(v*2,l,mid,a,b,nl1,mid);
                    add(v*2+1,mid+1,r,a,b,mid+1,nr1);   
                }
            }else{
                //one side
                int mid=((l+r)%2!=0)?(l+r-1)/2:(l+r)/2;
                if(nr<=mid) add(v*2,l,mid,a,b,nl,nr);
                else if(nl>mid) add(v*2+1,mid+1,r,a,b,nl,nr);
                else{
                    add(v*2,l,mid,a,b,nl,mid);
                    add(v*2+1,mid+1,r,a,b,mid+1,nr);    
                }
            }
        }
    }
    if(l==r) return;
}

LL query(LL v,LL l,LL r,LL x,LL s){
    if(f[v].a>XXX)s=max(s,val(f[v].a,f[v].b,x));
    if(l==r) return s;
    int mid=((l+r)%2!=0)?(l+r-1)/2:(l+r)/2;
    if(x<=mid) return query(v*2,l,mid,x,s);
    else return query(v*2+1,mid+1,r,x,s);
}

int main(){
    freopen("a.in","r",stdin);
    freopen("a.out","w",stdout);
    N=read();
    Q=read();
    LL i,j;
    
    for (i=1;i<=N;++i)
        a[i]=read(),b[i]=read();
    memset(f,128,sizeof(f));
    minx=1e18;
    maxx=-1e18;
    for (i=1;i<=Q;++i){
        x[i]=read();
        minx=min(x[i],minx);
        maxx=max(x[i],maxx);
    }
    
    for (i=1;i<=N;++i)
        add(1,minx,maxx,a[i],b[i],minx,maxx);
    
    for (i=1;i<=Q;++i)
        printf("%lld\n",query(1,minx,maxx,x[i],-1e18));
}

Guess you like

Origin www.cnblogs.com/Chandery/p/11468241.html