• uoj#191. 【集训队互测2016】Unknown


    http://uoj.ac/problem/191

    zkw线段树维护区间凸包,由于凸包的上传需要归并排序,为保证均摊复杂度,一个点只在同一层的右边一个点对应的区间插入完毕时才上传信息,删除时则清除被删除叶子到根的路径的信息,查询则在凸包上二/三分。

    #include<bits/stdc++.h>
    typedef long long i64;
    const int M=1e5,N=300007,P=998244353,mx=524288;
    char ib[M+7],*ip=ib+M;
    int G(){
        if(ip==ib+M)fread(ip=ib,1,M,stdin)[ib]=0;
        return *ip++;
    }
    int _(){
        int x=0,f=1;
        if(ip<ib+M-100){
            while(*ip<48)*ip++=='-'?f=-1:0;
            while(*ip>47)x=x*10+*ip++-48;
        }else{
            int c=G();
            while(c<48)c=='-'?f=-1:0,c=G();
            while(c>47)x=x*10+c-48,c=G();
        }
        return x*f;
    }
    struct pos{
        int x,y;
        i64 operator*(const pos&w)const{return i64(x)*w.y-i64(y)*w.x;}
        pos operator-(const pos&w)const{return (pos){x-w.x,y-w.y};}
    }ps[20][N],*tr[mx+N],*_a;
    int cnt[mx+N],now=0,_p;
    void ins(const pos&p){
        if(_p&&_a[_p-1].x==p.x){
            if(_a[_p-1].y>=p.y)return;
            --_p;
        }
        while(_p>1&&(_a[_p-2]-_a[_p-1])*(p-_a[_p-1])<=0)--_p;
        _a[_p++]=p;
    }
    void up(int w){
        if(cnt[w])return;
        _a=tr[w];_p=0;
        pos*ls=tr[w<<1],*le=ls+cnt[w<<1],*rs=tr[w<<1^1],*re=rs+cnt[w<<1^1];
        while(ls!=le&&rs!=re)ins(ls->x<rs->x?*ls++:*rs++);
        while(ls!=le)ins(*ls++);
        while(rs!=re)ins(*rs++);
        cnt[w]=_p;
    }
    void push(){
        int x=_(),y=_(),w=mx+(++now);
        cnt[w]=1;
        *tr[w]=(pos){x,y};
        for(;w&1;w>>=1,up(w-1));
    }
    void pop(){
        for(int w=mx+now-->>1;cnt[w]>0;w>>=1)cnt[w]=0;
    }
    void maxs(i64&a,i64 b){if(a<b)a=b;}
    i64 que(int w,pos p){
        if(!cnt[w])return std::max(que(w<<1,p),que(w<<1^1,p));
        pos*a=tr[w];
        int L=0,R=cnt[w]-1,M;
        while(R-L>5)(M=L+R>>1,p*a[M]>p*a[M+1])?(R=M):(L=M+1);
        i64 v=p*a[L++];
        while(L<=R)maxs(v,p*a[L++]);
        return v;
    }
    int query(){
        i64 ans=-(1ll<<61);
        int l=_(),r=_(),x=_(),y=_();
        pos p=(pos){x,y};
        for(l+=mx-1,r+=mx+1;r-l!=1;l>>=1,r>>=1){
            if(~l&1)maxs(ans,que(l+1,p));
            if(r&1)maxs(ans,que(r-1,p));
        }
        x=ans%P;
        return x<0?x+P:x;
    }
    int main(){
        _();
        for(int m,sum;sum=now=0,m=_();printf("%u
    ",sum)){
            for(int l=mx,r=mx+std::min(300005,m),dep=0;l;l>>=1,r>>=1,++dep){
                for(int i=l;i<=r;++i)tr[i]=ps[dep]+(i-l<<dep),cnt[i]=0;
            }
            for(int w=mx;w;w>>=1)cnt[w]=cnt[w-1]=-1;
            for(;m;--m){
                int o=_();
                if(o==1)push();
                else if(o==2)pop();
                else sum^=query();
            }
        }
        return 0;
    }
  • 相关阅读:
    接口分类
    HTTPS和HTTP的主要区别
    协议类
    小程序
    Polyfill
    去重数组
    odoo 接口跨域请求报错
    docker-compose 自定义容器名称
    linux ssh 防暴力破解fail2ban
    odoo 知识点
  • 原文地址:https://www.cnblogs.com/ccz181078/p/7566867.html
Copyright © 2020-2023  润新知