wblt 84 pts MLE 求调,悬一关

P6136 【模板】普通平衡树(数据加强版)

zzzyyyyhhhhh @ 2024-12-30 21:28:22

#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1e5+100;
const double mxx=1.5;
int a[N];
struct node
{
    int mx,mi;
    int cnt;
    node *ll,*rr;
    node(){mx=cnt=0,ll=rr=0;}
    node(int vv){mx=mi=vv,cnt=1,ll=rr=0;}
    inline void up(){cnt=((ll->cnt)+rr->cnt),mx=max(ll->mx,rr->mx),mi=min(ll->mi,rr->mi);}
    inline void build(int l,int r)
    {
        if(l==r){mi=mx=a[l];cnt=1;return;}
        ll=new node,rr=new node;
        ll->build(l,(l+r)>>1),rr->build(((l+r)>>1)+1,r);
        up();
    }
    inline void Lr()//L is bigger
    {
        node *rn=new node,*gar=ll;
        rn->ll=gar->rr,rn->rr=rr;
        rr=rn,rn->up();
        ll=gar->ll;
        delete gar;
    }
    inline void Rr()//R is bigger
    {
        node *ln=new node,*gar=rr;
        ln->ll=ll,ln->rr=gar->ll;
        ll=ln,ln->up();
        rr=gar->rr;
        delete gar;
    }
    inline void chk()
    {
        if(ll->cnt-rr->cnt>=rr->cnt*mxx)Lr();
        if(rr->cnt-ll->cnt>=ll->cnt*mxx)Rr();
    }
    inline void add(int vv)
    {
        if((!ll)&&(!rr))
        {
            if(mx<=vv)
                ll=new node(mx),rr=new node(vv);
            else
                rr=new node(mx),ll=new node(vv);
            up();
            return;
        }
        if(vv<=ll->mx)ll->add(vv);
        else rr->add(vv);
        up();
        chk();
    }
    inline void del(int vv)
    {
        if(ll->mx>=vv)
        {
            if((!ll->ll)&&(!ll->rr))
            {
                delete ll;
                node *t=rr;
                mx=t->mx,mi=t->mi,cnt=t->cnt,ll=t->ll,rr=t->rr;
                delete t;
                if(ll)up();
                return;
            }
            ll->del(vv);
        }
        else
        {
            if((!rr->ll)&&(!rr->rr))
            {
                delete rr;
                node *t=ll;
                mx=t->mx,mi=t->mi,cnt=t->cnt,ll=t->ll,rr=t->rr;
                delete t;
                if(ll)up();
                return;
            }
            rr->del(vv);
        }
        chk();
        up();
    }
    inline int less(int vv)
    {
        if(mi>=vv)return 0;
        if(mx<vv)return cnt;
        if(ll->mx<vv)return ll->less(vv)+rr->less(vv);
        return ll->less(vv);
    }
    inline int get(int k)
    {
        if((!ll)&&(!rr))return mx;
        if(ll->cnt>=k)return ll->get(k);
        return rr->get(k-ll->cnt);
    }
    inline int front(int vv)
    {
        if((!ll)&&(!rr))return mx;
        if(rr->mi<vv)return rr->front(vv);
        return ll->front(vv);
    }
    inline int beh(int vv)
    {
        if((!ll)&&(!rr))return mx;
        if(ll->mx>vv)return ll->beh(vv);
        return rr->beh(vv);
    }
}t;
signed main()
{
    // ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int n,m,op,x,ls=0,ans=0;
    cin>>n>>m;
    for(int i=1;i<=n;i++)cin>>a[i];
    sort(a+1,a+1+n);
    t.build(1,n);
    t.add(-2e9);
    while(m--)
    {
        cin>>op>>x;
        x^=ls;
        if(op==1)t.add(x);
        else if(op==2)t.del(x);
        else if(op==3)ls=t.less(x),ans^=ls;
        else if(op==4)ls=t.get(x+1),ans^=ls;
        else if(op==5)ls=t.front(x),ans^=ls;
        else ls=t.beh(x),ans^=ls;
        // cout<<ls<<'\n';
    }
    cout<<ans;
}

by zzzyyyyhhhhh @ 2024-12-30 22:19:01

改为类权值线段树 92pts。

#include<iostream>
#include<algorithm>
using namespace std;
const int N = 1e5+100;
const double mxx=1.5;
int a[N];
struct node
{
    int mx,mi;
    int cnt,siz;
    node *ll,*rr;
    node(){mx=cnt=0,ll=rr=0;}
    node(int vv,int cc){mx=mi=vv,siz=1,cnt=cc,ll=rr=0;}
    inline void up(){cnt=((ll->cnt)+rr->cnt),siz=(ll->siz+rr->siz),mx=max(ll->mx,rr->mx),mi=min(ll->mi,rr->mi);}
    inline void build(int l,int r)
    {
        if(l==r){mi=mx=a[l];cnt=1;return;}
        ll=new node,rr=new node;
        ll->build(l,(l+r)>>1),rr->build(((l+r)>>1)+1,r);
        up();
    }
    inline void Lr()//L is bigger
    {
        node *rn=new node,*gar=ll;
        rn->ll=gar->rr,rn->rr=rr;
        rr=rn;
        rn->up();
        ll=gar->ll;
        delete gar;
    }
    inline void Rr()//R is bigger
    {
        node *ln=new node,*gar=rr;
        ln->ll=ll,ln->rr=gar->ll;
        ll=ln;
        ln->up();
        rr=gar->rr;
        delete gar;
    }
    inline void chk()
    {
        if(ll->siz-rr->siz>=rr->siz*mxx)Lr();
        if(rr->siz-ll->siz>=ll->siz*mxx)Rr();
    }
    inline void add(int vv)
    {
        if((!ll)&&(!rr))
        {
            if(mx==vv){cnt++;return;}
            if(mx<=vv)
                ll=new node(mx,cnt),rr=new node(vv,1);
            else
                rr=new node(mx,cnt),ll=new node(vv,1);
            up();
            return;
        }
        if(vv<=ll->mx)ll->add(vv);
        else rr->add(vv);
        up();
        chk();
    }
    inline void del(int vv)
    {
        if(ll->mx>=vv)
        {
            if((!ll->ll)&&(!ll->rr))
            {
                ll->cnt--,cnt--;
                if(!ll->cnt)
                {
                    delete ll;
                    node *t=rr;
                    mx=t->mx,mi=t->mi,cnt=t->cnt,siz=t->siz,ll=t->ll,rr=t->rr;
                    delete t;
                    if(ll)up();
                }
                return;
            }
            ll->del(vv);
        }
        else
        {
            if((!rr->ll)&&(!rr->rr))
            {
                rr->cnt--,cnt--;
                if(!rr->cnt)
                {
                    delete rr;
                    node *t=ll;
                    mx=t->mx,mi=t->mi,cnt=t->cnt,siz=t->siz,ll=t->ll,rr=t->rr;
                    delete t;
                    if(ll)up();
                }
                return;
            }
            rr->del(vv);
        }
        chk();
        up();
    }
    inline int less(int vv)
    {
        if(mx<vv)return cnt;
        if(ll->mx<vv&&rr->mi<vv)return ll->less(vv)+rr->less(vv);
        return ll->less(vv);
    }
    inline int get(int k)
    {
        if((!ll)&&(!rr))return mx;
        if(ll->cnt>=k)return ll->get(k);
        return rr->get(k-ll->cnt);
    }
    inline int front(int vv)
    {
        if((!ll)&&(!rr))return mx;
        if(rr->mi<vv)return rr->front(vv);
        return ll->front(vv);
    }
    inline int beh(int vv)
    {
        if((!ll)&&(!rr))return mx;
        if(ll->mx>vv)return ll->beh(vv);
        return rr->beh(vv);
    }
}t;
signed main()
{
    // freopen("in.in","r",stdin);
    // freopen("out.out","w",stdout);
    ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int n,m,op,x,ls=0,ans=0;
    cin>>n>>m;
    t.mx=t.mi=-2e9;
    t.siz=t.cnt=1;
    for(int i=1;i<=n;i++)cin>>x,t.add(x);
    while(m--)
    {
        cin>>op>>x;
        x^=ls;
        if(op==1)t.add(x);
        else if(op==2)t.del(x);
        else if(op==3)ls=t.less(x),ans^=ls;
        else if(op==4)ls=t.get(x+1),ans^=ls;
        else if(op==5)ls=t.front(x),ans^=ls;
        else ls=t.beh(x),ans^=ls;
    }
    cout<<ans;
}

|