BZOJ3533: [Sdoi2014]向量集

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/liutian429073576/article/details/51830567

APIO张鑫同学跟我说的
现在才填好坑
求出当点Pi优于Pj的条件
发现直接线段树节点上建上下凸壳然后二分就好了

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
#define ll long long
char c;
bool flag;
inline void read(ll &a){a=0;do c=getchar();while(c!='-'&&(c<'0'||c>'9'));c=c=='-'?flag=true,getchar():c;while(c<='9'&&c>='0')a=(a<<3)+(a<<1)+c-'0',c=getchar();a=(flag?flag=false,-a:a);}
const
    double eps=1e-7;


struct P
{
    ll x,y;
    inline friend ll operator *(P a,P b){return a.x*b.y-a.y*b.x;}
    P(){}
    P(ll x,ll y):x(x),y(y){}
    inline friend P operator -(P a,P b){return P(a.x-b.x,a.y-b.y);}
    inline friend bool operator <(P a,P b){return a.x^b.x?a.x<b.x:a.y<b.y;}
}L[600001];
ll n;
inline bool cmp(ll a,ll b){return L[a]<L[b];}
ll stack[600001];
ll cache[600001];
struct Node
{
    ll *rstack,*lstack;
    ll rtop,ltop;
    Node *lc,*rc;
    ll l,r;
    Node():lc(NULL),rc(NULL){}
    Node(ll l,ll r,Node *lc,Node *rc):lc(lc),rc(rc),l(l),r(r){}
    inline void bg()
    {
        ll i,top=0,n=0;
        for(i=1;i<=rc->rtop;i++)
                    cache[++n]=rc->rstack[i-1];
        for(i=1;i<=lc->rtop;i++)
                    cache[++n]=lc->rstack[i-1];  
        sort(cache+1,cache+1+n,cmp);
        stack[1]=cache[1],stack[2]=cache[top=2];
        for(ll i=3;i<=n;i++)
            {
                while(top>1&&(L[stack[top]]-L[stack[top-1]])*(L[cache[i]]-L[stack[top-1]])>=0)top--;
                stack[++top]=cache[i];
            }
        rstack=new ll [rtop=top];
        for(i=1;i<=top;i++)
            rstack[i-1]=stack[i];
        top=0,n=0;
        for(i=1;i<=lc->ltop;i++)
                    cache[++n]=lc->lstack[i-1];
        for(i=1;i<=rc->ltop;i++)
                    cache[++n]=rc->lstack[i-1];  
        sort(cache+1,cache+1+n,cmp);
        stack[1]=cache[1],stack[2]=cache[top=2];
        for(ll i=3;i<=n;i++)
            {
                while(top>1&&(L[stack[top]]-L[stack[top-1]])*(L[cache[i]]-L[stack[top-1]])<=0)top--;
                stack[++top]=cache[i];
            }
        lstack=new ll [ltop=top];
        for(ll i=1;i<=top;i++)
            lstack[i-1]=stack[i];

    }
    inline void B(ll l)
    {
        lstack=new ll [rtop=ltop=1];
        rstack=new ll [1];
        lstack[0]=rstack[0]=l;
    }
    inline ll Query(ll x,ll y)
    {
        if(r-l==0)
            return L[l].x*x+L[l].y*y;
        if(r-l==1)return max(L[l].x*x+L[l].y*y,L[r].x*x+L[r].y*y);
        if(y==0)
        {
            if(x<0)return L[lstack[0]].x*x;
            return L[lstack[ltop-1]].x*x;
        }
        else    if(y>0)
        {
            ll mid,l=0,r=rtop-2;
            while(l<r)
            {
                mid=(l+r>>1);
                if((L[rstack[mid+1]].y-L[rstack[mid]].y)/(eps+L[rstack[mid+1]].x-L[rstack[mid]].x)>=-x/(eps+y))l=mid+1;
                else r=mid;
            }
            return max(L[rstack[l]].x*x+L[rstack[l]].y*y,L[rstack[l+1]].x*x+L[rstack[l+1]].y*y);
        }
        else
        {
            ll mid,l=0,r=ltop-2;
            while(l<r)
            {
                mid=(l+r>>1);
                if((L[lstack[mid+1]].y-L[lstack[mid]].y)/(eps+L[lstack[mid+1]].x-L[lstack[mid]].x)<=-x/(eps+y))l=mid+1;
                else r=mid;
            }
            return max(L[lstack[l]].x*x+L[lstack[l]].y*y,L[lstack[l+1]].x*x+L[lstack[l+1]].y*y);
        }
    }
};


inline ll Cg(ll &x,ll lastans) {
     return x ^=(lastans & 0x7fffffff);
}

Node T[2000001];
const
ll INF=1ll<<61;
inline ll Max(ll&a,ll b){return a>b?a:a=b;}
ll Query(ll place,ll x,ll y,ll l,ll r)
{if(T[place].l>=l&&T[place].r<=r)return T[place].Query(x,y);ll a=-INF;ll lc=place<<1,rc=lc|1,mid=T[lc].r;if(mid>=l)Max(a,Query(lc,x,y,l,r));if(mid<r)Max(a,Query(rc,x,y,l,r));return a;}
void Modify(ll place,ll l)
{if(T[place].l==T[place].r)return T[place].B(l);int mid=T[place<<1].r;if(mid<l)Modify(place<<1|1,l);else Modify(place<<1,l);if(l==T[place].r)T[place].bg();}
ll C;
void Build(ll place,ll l,ll r)
{if(l^r)Build(place<<1,l,l+r>>1),Build(place<<1|1,(l+r>>1)+1,r);T[place]=Node(l,r,T+(place<<1),T+(place<<1|1));}
int main()
{
    read(n);
    c=getchar();    
    bool I=false;
    if(c!='E')I=true;
    Build(1,1,n);
    ll ans=0,x,y,l,r;
    while(n--)
    {do c=getchar();while(c!='A'&&c!='Q');if(c=='A'){read(L[++C].x),read(L[C].y);if(I)Cg(L[C].x,ans),Cg(L[C].y,ans);Modify(1,C);}else{read(x),read(y),read(l),read(r);if(I)Cg(x,ans),Cg(y,ans),Cg(l,ans),Cg(r,ans);ans=Query(1,x,y,l,r);printf("%lld\n",ans);}}
    return 0;
}
阅读更多
想对作者说点什么?
相关热词

博主推荐

换一批

没有更多推荐了,返回首页