bzoj3224

Posted せみしぐれ

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj3224相关的知识,希望对你有一定的参考价值。

这道题是看着别人的板子大的,思路不难,但过程里有很多细节要注意

首先是treap

/**************************************************************
    Problem: 3224
    Language: C++
    Result: Accepted
    Time:300 ms
    Memory:3164 kb
****************************************************************/
 
#include<cstdio>
#include<cctype>
#include<algorithm>
using namespace std;
int n,rt,size;
struct data{
    int l,r,val,cnt,siz,rnd;
}tr[100005];
 
inline int read(){
    char ch=getchar();int k=0,f=1;
    while(!isdigit(ch)) {if(ch==-) f=-1;ch=getchar();}
    while(isdigit(ch)){k=(k<<1)+(k<<3)+ch-0;ch=getchar();}
    return k*f;
}
 
inline void update(int root){
    tr[root].siz=tr[tr[root].l].siz+tr[tr[root].r].siz+tr[root].cnt;
}
 
inline int rand(){
    static int seed = 2333;
    return seed = (int)((((seed ^ 998244353) + 19260817ll) * 19890604ll) % 1000000007);
}
 
void lturn(int &root){
    int t=tr[root].r;tr[root].r=tr[t].l;tr[t].l=root;
    tr[t].siz=tr[root].siz;update(root);root=t;
}
 
void rturn(int &root){
    int t=tr[root].l;tr[root].l=tr[t].r;tr[t].r=root;
    tr[t].siz=tr[root].siz;update(root);root=t;
}
 
void _insert(int &root,int now){
    if(root==0){
        root=++size;tr[root].siz=tr[root].cnt=1;tr[root].val=now;tr[root].rnd=rand();return;
    }
    tr[root].siz++;
    if(tr[root].val==now) tr[root].cnt++;
    else if(tr[root].val>now){
        _insert(tr[root].l,now);
        if(tr[root].rnd>tr[tr[root].l].rnd) rturn(root);
    }
    else{
        _insert(tr[root].r,now);
        if(tr[root].rnd>tr[tr[root].r].rnd) lturn(root);
    }
}
 
void _del(int &root,int now){
    if(root==0) return;
    if(tr[root].val==now){
        if(tr[root].cnt>1){tr[root].cnt--;tr[root].siz--;}
        else if(tr[root].l==0 || tr[root].r==0) root=tr[root].l+tr[root].r;
        else if(tr[tr[root].r].rnd>tr[tr[root].l].rnd) rturn(root),_del(root,now);
        else lturn(root),_del(root,now);
    }
    else if(tr[root].val>now) tr[root].siz--,_del(tr[root].l,now);
    else tr[root].siz--,_del(tr[root].r,now);
}
 
int query_xpm(int root,int now){
    if(root==0) return 0;
    if(tr[root].val==now) return tr[tr[root].l].siz+1;
    if(tr[root].val<now) return tr[tr[root].l].siz+tr[root].cnt+query_xpm(tr[root].r,now);
    else return query_xpm(tr[root].l,now);
}
 
int query_pmx(int root,int now){
    if(root==0) return 0;
    if(tr[tr[root].l].siz<now && tr[root].cnt+tr[tr[root].l].siz>=now) return tr[root].val;
    else if(now<=tr[tr[root].l].siz) return query_pmx(tr[root].l,now);
    else return query_pmx(tr[root].r,now-tr[tr[root].l].siz-tr[root].cnt);
}
 
int query_qq(int root,int now){
    if(root==0) return -2e9;
    if(tr[root].val>=now) return query_qq(tr[root].l,now);
    else return max(tr[root].val,query_qq(tr[root].r,now));
}
 
int query_hj(int root,int now){
    if(root==0) return 2e9;
    if(tr[root].val<=now) return query_hj(tr[root].r,now);
    else return min(tr[root].val,query_hj(tr[root].l,now));
}
 
int main(){
    n=read();
    int flag,x;
    for(int i=1;i<=n;i++){
        flag=read();x=read();
        if(flag==1) _insert(rt,x);
        if(flag==2) _del(rt,x);
        if(flag==3) printf("%ld\n",query_xpm(rt,x));
        if(flag==4) printf("%ld\n",query_pmx(rt,x));
        if(flag==5) printf("%ld\n",query_qq(rt,x));
        if(flag==6) printf("%ld\n",query_hj(rt,x));
    }
    return 0;
}

然后是splay

/**************************************************************
    Problem: 3224
    Language: C++
    Result: Accepted
    Time:720 ms
    Memory:24740 kb
****************************************************************/
 
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
#define maxn 1000005
int tr[maxn][2],f[maxn],siz[maxn],cnt[maxn],key[maxn];
int sz,rt;
 
inline void clear(int x){
    tr[x][0]=tr[x][1]=f[x]=siz[x]=cnt[x]=key[x]=0;
}
 
inline void updata(int x){
    if(x){
        siz[x]=cnt[x];
        if(tr[x][0])siz[x]+=siz[tr[x][0]];
        if(tr[x][1])siz[x]+=siz[tr[x][1]];
    }
}
 
inline void rotate(int x){
    int old=f[x],oldf=f[old],whicx=(tr[f[x]][1]==x);
    tr[old][whicx]=tr[x][whicx^1];f[tr[old][whicx]]=old;
    tr[x][whicx^1]=old;f[old]=x;
    f[x]=oldf;
    if(oldf)tr[oldf][tr[oldf][1]==old]=x;
    updata(old);updata(x);
}
 
inline void splay(int x){
    for(int fa;fa=f[x];rotate(x))
        if(f[fa])rotate((tr[f[x]][1]==x)==(tr[f[fa]][1]==fa)?fa:x);
    rt=x;
}
inline void insert(int x){
    if(rt==0){sz++;tr[sz][0]=tr[sz][1]=f[sz]=0;rt=sz;siz[sz]=cnt[sz]=1;key[sz]=x;return;}
    int now=rt,fa=0;
    while(1){
        if(x==key[now]){
            cnt[now]++;updata(now);updata(fa);splay(now);break;
        }
        fa=now;
        now=tr[now][key[now]<x];
        if(now==0){
            sz++;
            tr[sz][0]=tr[sz][1]=0;
            f[sz]=fa;
            siz[sz]=cnt[sz]=1;
            tr[fa][key[fa]<x]=sz;
            key[sz]=x;
            updata(fa);
            splay(sz);
            break;
        }
    }
}
inline int find(int x){
    int now=rt,ans=0;
    while(1){
        if(x<key[now])now=tr[now][0];
        else{
            ans+=(tr[now][0]?siz[tr[now][0]]:0);
            if(x==key[now]){splay(now);return ans+1;}
            ans+=cnt[now];
            now=tr[now][1];
        }
    }
}
inline int findx(int x){
    int now=rt;
    while(1){
        if(tr[now][0]&&x<=siz[tr[now][0]])now=tr[now][0];
        else{
            int tmp=(tr[now][0]?siz[tr[now][0]]:0)+cnt[now];
            if(x<=tmp)return key[now];
            x-=tmp;now=tr[now][1];
        }
    }
}
inline int pre(){
    int now=tr[rt][0];
    while(tr[now][1])now=tr[now][1];
    return now;
}
inline int next(){
    int now=tr[rt][1];
    while(tr[now][0])now=tr[now][0];
    return now;
}
inline void del(int x){
    int whtev=find(x);
    if(cnt[rt]>1){cnt[rt]--;updata(rt);return;}
    if(!tr[rt][0]&&!tr[rt][1]){clear(rt);rt=0;return;}
    if(!tr[rt][0]){
        int oldrt=rt;rt=tr[rt][1];f[rt]=0;clear(oldrt);return;
    }
    else if(!tr[rt][1]){
        int oldrt=rt;rt=tr[rt][0];f[rt]=0;clear(oldrt);return;
    }
    int lefb=pre(),oldrt=rt;
    splay(lefb);
    tr[rt][1]=tr[oldrt][1];
    f[tr[oldrt][1]]=rt;
    clear(oldrt);
    updata(rt); 
}
 
int main(){
    int n,opt,x;
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d%d",&opt,&x);
        switch(opt){
            case 1:insert(x);break;
            case 2:del(x);break;
            case 3:printf("%d\n",find(x));break;
            case 4:printf("%d\n",findx(x));break;
            case 5:insert(x);printf("%d\n",key[pre()]);del(x);break;
            case 6:insert(x);printf("%d\n",key[next()]);del(x);break;
        }
    }
}

 

以上是关于bzoj3224的主要内容,如果未能解决你的问题,请参考以下文章

bzoj3224

BZOJ3224: Tyvj 1728 普通平衡树

[bzoj3224]普通平衡树

bzoj3224: Tyvj 1728 普通平衡树(spaly)

不可能的任务22/200填坑bzoj3224 splay裸题

bzoj3224