線段樹套平衡樹
阿新 • • 發佈:2022-04-15
沒什麼好講的,直接碼就完了。
#include<bits/stdc++.h> #define ll long long #define db double #define filein(a) freopen(#a".in","r",stdin) #define fileot(a) freopen(#a".out","w",stdout) #define Better_IO false namespace IO{ #if Better_IO char buf[(1<<20)+3],*p1(buf),*p2(buf); const int lim=1<<20; inline char gc(){ if(p1==p2) p2=(p1=buf)+fread(buf,1,lim,stdin); return p1==p2?EOF:*p1++; } #define pc putchar #else #define gc getchar #define pc putchar #endif inline bool blank(char c){ return c=='\t' or c=='\n' or c=='\r' or c==' ' or c==EOF; } inline void gs(char *s){ char ch=gc(); while(blank(ch) ) ch=gc(); while(!blank(ch) ) {*s++=ch;ch=gc();} *s=0; } inline void ps(char *s){ while(*s!=0) {pc(*s++);} } template<class T> inline void read(T &s){ s=0;char ch=gc();bool f=0; while(ch<'0'||'9'<ch) {if(ch=='-') f=1;ch=gc();} while('0'<=ch&&ch<='9') {s=s*10+(ch^48);ch=gc();} if(ch=='.'){ db p=0.1;ch=gc(); while('0'<=ch&&ch<='9') {s=s+p*(ch^48);ch=gc();p*=0.1;} } s=f?-s:s; } template<class T,class ...A> inline void read(T &s,A &...a){ read(s);read(a...); } }; using IO::gs; using IO::ps; using IO::read; const int N=5e4+3; const int inf=1e9; int n,m; int a[N]; struct Scapegoat{ #define lc(x) t[x].lc #define rc(x) t[x].rc const db alpha=0.7; int tot; struct node{ int lc,rc,cnt; int k,sz,fc; }t[(N<<1)*16*16]; inline void pushup(int x){ t[x].sz=t[lc(x)].sz+t[rc(x)].sz+1; t[x].fc=t[lc(x)].fc+t[rc(x)].fc+t[x].cnt; } inline bool canrbu(int x){ return t[x].cnt and ( t[x].sz*alpha<=(db)std::max(t[lc(x)].sz,t[rc(x)].sz) or (db)t[x].fc<=t[x].sz*alpha ); } int top,fd[(N<<1)*16]; void rbu_ldr(int x){ if(!x) return; rbu_ldr(lc(x) ); if(t[x].cnt) fd[++top]=x; rbu_ldr(rc(x) ); } int rbu_build(int l,int r){ if(l>r) return 0; int mid=(l+r)>>1; lc(fd[mid])=rbu_build(l,mid-1); rc(fd[mid])=rbu_build(mid+1,r); pushup(fd[mid]); return fd[mid]; } inline void rbu(int &x){ top=0;rbu_ldr(x); x=rbu_build(1,top); } void ins(int &x,int k){ if(!x){ x=++tot; t[x].k=k; ++t[x].cnt; pushup(x); return; } if(t[x].k==k){ ++t[x].cnt; }else if(t[x].k<k){ ins(rc(x),k); }else{ ins(lc(x),k); } pushup(x); if(canrbu(x) ) rbu(x); } void del(int &x,int k){ if(!x) return; if(t[x].k==k){ if(t[x].cnt) --t[x].cnt; }else if(t[x].k<k){ del(rc(x),k); }else{ del(lc(x),k); } pushup(x); if(canrbu(x) ) rbu(x); } int upper(int x,int k){ if(!x) return 0; if(t[x].k==k) return t[lc(x)].fc; if(k<t[x].k) return upper(lc(x),k); return t[lc(x)].fc+t[x].cnt+upper(rc(x),k); } int kth(int x,int k){ if(!x) return 0; if(t[lc(x)].fc<k and k<=t[lc(x)].fc+t[x].cnt) return t[x].k; if(k<=t[lc(x)].fc) return kth(lc(x),k); return kth(rc(x),k-t[lc(x)].fc-t[x].cnt); } inline int pre(int x,int k){ int s=upper(x,k); if(s<=0) return -inf; return kth(x,s); } inline int nxt(int x,int k){ int s=upper(x,k+1)+1; if(s>t[x].fc) return inf; return kth(x,s); } #undef lc #undef rc }s2; struct SegTree{ #define lc(x) (x<<1) #define rc(x) (x<<1|1) struct node{ int l,r,mid; int rt; }t[N<<2]; inline void build(int x,int l,int r){ t[x].l=l;t[x].r=r;t[x].mid=(l+r)>>1; for(int i=l;i<=r;++i){ s2.ins(t[x].rt,a[i]); } if(l==r){ return; } build(lc(x),l,t[x].mid); build(rc(x),t[x].mid+1,r); } inline int upper(int x,int l,int r,int k){ if(l<=t[x].l and t[x].r<=r){ return s2.upper(t[x].rt,k); } int res=0; if(l<=t[x].mid) res+=upper(lc(x),l,r,k); if(t[x].mid+1<=r) res+=upper(rc(x),l,r,k); return res; } inline void modify(int x,int p,int a,int b){ s2.del(t[x].rt,a); s2.ins(t[x].rt,b); if(p<=t[x].l and t[x].r<=p){ return; } if(p<=t[x].mid) modify(lc(x),p,a,b); if(t[x].mid+1<=p) modify(rc(x),p,a,b); } inline int pre(int x,int l,int r,int k){ if(l<=t[x].l and t[x].r<=r){ return s2.pre(t[x].rt,k); } int res=-inf; if(l<=t[x].mid) res=std::max(res,pre(lc(x),l,r,k) ); if(t[x].mid+1<=r) res=std::max(res,pre(rc(x),l,r,k) ); return res; } inline int nxt(int x,int l,int r,int k){ if(l<=t[x].l and t[x].r<=r){ return s2.nxt(t[x].rt,k); } int res=inf; if(l<=t[x].mid) res=std::min(res,nxt(lc(x),l,r,k) ); if(t[x].mid+1<=r) res=std::min(res,nxt(rc(x),l,r,k) ); return res; } #undef lc #undef rc }s1; int main(){ //filein(a);fileot(a); read(n,m); for(int i=1;i<=n;++i){ read(a[i]); } s1.build(1,1,n); for(int i=1;i<=m;++i){ int op;read(op); int l,r,p,k; int t=clock(); if(op==1){ read(l,r,k); printf("%d\n",s1.upper(1,l,r,k)+1); } if(op==2){ read(l,r,k); int el=0,er=1e8,eres=0; int tim=0; while(el<=er){ ++tim; int emid=(el+er)>>1; if(s1.upper(1,l,r,emid)<k){ el=emid+1;eres=emid; }else er=emid-1; } printf("%d\n",eres); } if(op==3){ read(p,k); s1.modify(1,p,a[p],k); a[p]=k; } if(op==4){ read(l,r,k); int s=s1.pre(1,l,r,k); if(s!=-inf) printf("%d\n",s); else printf("-2147483647\n"); } if(op==5){ read(l,r,k); int s=s1.nxt(1,l,r,k); if(s!=inf) printf("%d\n",s); else printf("2147483647\n"); } } fprintf(stderr,"%dms\n",clock() ); return 0; }