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: Tyvj 1728 普通平衡树(spaly)