标签:复杂度 can pre new print 而且 delete 树套树 stream
来一发树套树。1A也是很感动QAQ
就是时间复杂度略大。而且好像还有其他打法。
谨以此纪念此类型树套树入门
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> using namespace std; #define pos(i,a,b) for(int i=(a);i<=(b);i++) #define N 51000 #define size(x) ((x)?(x->size):(0)) #define lc(x) (x->ch[0]) #define rc(x) (x->ch[1]) int n,m; struct Treap{ Treap *ch[2]; int v,key,size; Treap(int x=0){ ch[0]=ch[1]=NULL;key=rand();size=1;v=x; } }*root[N*4]; void pushup(Treap *rt){ rt->size=size(lc(rt))+size(rc(rt))+1; } void turn(Treap *&rt,int d){ Treap *t=rt->ch[d^1]; rt->ch[d^1]=t->ch[d]; pushup(rt); t->ch[d]=rt; pushup(t); rt=t; } void insert(Treap *&rt,int x){ if(!rt){ rt=new Treap(x);return; } int d=x < rt->v; insert(rt->ch[d^1],x); pushup(rt); if(rt->key > rt->ch[d^1]->key) turn(rt,d); } void del(Treap *&rt,int x){ if(rt->v == x){ if(lc(rt)&&rc(rt)){ int d=lc(rt)->key < rc(rt)->key; turn(rt,d); del(rt->ch[d],x); } else{ Treap *t=NULL; if(lc(rt)) t=lc(rt); else t=rc(rt); delete rt;rt=t; } } else{ int d=rt->v < x; del(rt->ch[d],x); } if(rt) pushup(rt); } int pai(Treap *&rt,int x){ if(!rt) return 0; if(x<= rt->v){ return pai(lc(rt),x); } else return size(lc(rt))+1+pai(rc(rt),x); } int a[N]; void Insert(int l,int r,int rt){ pos(i,l,r) insert(root[rt],a[i]); } void build(int l,int r,int rt){ Insert(l,r,rt); if(l==r) return; int mid=(l+r)>>1; build(l,mid,rt<<1); build(mid+1,r,rt<<1|1); } void update(int l,int r,int pos,int x,int y,int rt){ del(root[rt],x);insert(root[rt],y); if(l==r) return; int mid=(l+r)>>1; if(pos<=mid) update(l,mid,pos,x,y,rt<<1); else update(mid+1,r,pos,x,y,rt<<1|1); } int Pai(int xl,int xr,int k,int l,int r,int rt){ if(l>=xl&&r<=xr) return pai(root[rt],k); int mid=(l+r)>>1; int ans(0); if(xl<=mid) ans+=Pai(xl,xr,k,l,mid,rt<<1); if(xr>mid) ans+=Pai(xl,xr,k,mid+1,r,rt<<1|1); return ans; } int kth(int L,int R,int k){ int l=0,r=(int)1e8; while(l<=r){ int mid=(l+r)>>1; if(Pai(L,R,mid,1,n,1)+1<=k) l=mid+1; else r=mid-1; } return r; } int main(){ scanf("%d%d",&n,&m); pos(i,1,n) scanf("%d",&a[i]); build(1,n,1); pos(i,1,m){ int opt;scanf("%d",&opt); int l,r,k; if(opt==3){ scanf("%d%d",&l,&k); update(1,n,l,a[l],k,1); a[l]=k; continue; } scanf("%d%d%d",&l,&r,&k); if(opt==1) printf("%d\n",Pai(l,r,k,1,n,1)+1); else if(opt==2) printf("%d\n",kth(l,r,k)); else if(opt==4) printf("%d\n",kth(l,r,Pai(l,r,k,1,n,1))); else if(opt==5) printf("%d\n",kth(l,r,Pai(l,r,k+1,1,n,1)+1)); } return 0; }
标签:复杂度 can pre new print 而且 delete 树套树 stream
原文地址:http://www.cnblogs.com/Hallmeow/p/7953775.html