动态开点的权值线段树搞普通平衡树。。。补发一波
Posted jackpei
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动态开点的权值线段树搞普通平衡树。。。补发一波相关的知识,希望对你有一定的参考价值。
RT.
#include<iostream> #include<cstdio> #define R register int using namespace std; inline int g() R ret=0,fix=1; register char ch; while(!isdigit(ch=getchar())) fix=ch==‘-‘?-1:fix; do ret=ret*10+(ch^48); while(isdigit(ch=getchar())); return ret*fix; const int N=100010,Inf=1E+7+10; struct node int ls,rs,cnt;t[N<<2]; int n,tot,rt; #define ls t[tr].ls #define rs t[tr].rs #define cnt(x) t[x].cnt inline void add(int& tr,int l,int r,int vl,int d) if(!tr) tr=++tot; if(l==r) cnt(tr)+=d; return ; R md=l+r>>1; if(vl<=md) add(ls,l,md,vl,d); else add(rs,md+1,r,vl,d); cnt(tr)=cnt(ls)+cnt(rs); inline int query(int tr,int l,int r,int LL,int RR) if(!tr) return 0; if(LL<=l&&r<=RR) return cnt(tr); R md=l+r>>1,ret=0; if(LL<=md) ret+=query(ls,l,md,LL,RR); if(RR>md) ret+=query(rs,md+1,r,LL,RR); return ret; inline int getvl(int tr,int l,int r,int rk) if(l==r) return l; R md=l+r>>1; if(cnt(ls)>=rk) return getvl(ls,l,md,rk); else return getvl(rs,md+1,r,rk-cnt(ls)); inline int getrk(int tr,int l,int r,int vl) if(!tr) return 0; if(l==r) return 1; R md=l+r>>1; if(vl<=md) return getrk(ls,l,md,vl); else return cnt(ls)+getrk(rs,md+1,r,vl); inline int getpre(int vl) R rk=query(1,-Inf,Inf,-Inf,vl-1); return getvl(1,-Inf,Inf,rk); inline int getnxt(int vl) R rk=query(1,-Inf,Inf,-Inf,vl)+1; return getvl(1,-Inf,Inf,rk); signed main() #ifdef JACK freopen("NOIPAK++.in","r",stdin); #endif n=g(); for(R i=1,op,x;i<=n;++i) op=g(),x=g(); if(op==1) add(rt,-Inf,Inf,x,1); else if(op==2) add(rt,-Inf,Inf,x,-1); else if(op==3) printf("%d\n",getrk(1,-Inf,Inf,x)); else if(op==4) printf("%d\n",getvl(1,-Inf,Inf,x)); else if(op==5) printf("%d\n",getpre(x)); else if(op==6) printf("%d\n",getnxt(x));
2019.07.03
以上是关于动态开点的权值线段树搞普通平衡树。。。补发一波的主要内容,如果未能解决你的问题,请参考以下文章