Title Description
You need to write a data structure (refer to the subject of the title), to maintain an orderly sequence, which need to provide the following:
1. k ranking queries within range
2. Query ranked within the range of values of k
3. Modify the value of a bit value
4. Query interval k in the precursor (precursor strictly defined as less than x, and the maximum number, if there -2147483647 output)
5. Query k in the subsequent interval (defined as successor strictly greater than x, and the smallest number, output if there 2147483647)
n- , m ≤ . 5 ⋅ . 1 0 . 4 to ensure that all the values in the ordered sequence satisfies any time [ 0 , . 1 0 . 8 ]
answer
These operations are common actions balance the tree, consider how maintenance intervals.
With a segment tree can, for the construction of a line segment sequence tree, each node maintains a splay, splay maintenance interval numbers.
1. As soon as the query how he can be smaller than the range of a few
2. not directly query, they can only recall two scores is the number 1 judge
3. delete and insert on a chain
4. Take max among all of the precursor cells found out
5. Remove min for all subsequent check out
The function code is written a bit more, very hard to accept, but still only in accordance with their own ideas to add
#include<bits/stdc++.h> using namespace std; const int maxn=50005; const int maxm=2000005; const int oo=2147483647; int n,m,o,cnt,num,ls[maxn<<1],rs[maxn<<1]; int a[maxn]; int root[maxn<<1]; struct Splay{ int fa,s[2],size,tag; int val; }tr[maxm]; template<class T>inline void read(T &x){ x=0;char ch=getchar(); while(!isdigit(ch)) ch=getchar(); while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();} } void update(int x){ tr[x].size=tr[tr[x].s[0]].size+tr[tr[x].s[1]].size+tr[x].tag; } int get(int x){ return tr[tr[x].fa].s[1]==x; } void connect(int x,int y,int d){ tr[x].fa=y; tr[y].s[d]=x; } void rotate(int x){ int f=tr[x].fa,ff=tr[f].fa; int d1=get(x),d2=get(f); int cs=tr[x].s[d1^1]; connect(x,ff,d2); connect(f,x,d1^1); connect(cs,f,d1); update(f); update(x); } void splay(int x,int go,int id){ if(go==root[id]) root[id]=x; go=tr[go].fa; while(tr[x].fa!=go){ int f=tr[x].fa; if(tr[f].fa==go) rotate(x); else if(get(f)==get(x)) {rotate(f);rotate(x);} else {rotate(x);rotate(x);} } } void insert(int val,int id){ int now=root[id]; if(!now){ root[id]=++num; tr[num]=(Splay){0,{0,0},1,1,val}; return ; } while(now){ tr[now].size++; if(tr[now].val==val){ tr[now].tag++; break; } int d=val>tr[now].val; if(!tr[now].s[d]){ tr[now].s[d]=++num; tr[num]=(Splay){now,{0,0},1,1,val}; now=num; break; } now=tr[now].s[d]; } splay(now,root[id],id); } void modify(int &rt,int l,int r,int pos,int val){ if(!rt) { rt=++cnt; insert(oo,rt); insert(-oo,rt); } insert(val,rt); if(l==r) return ; int mid=(l+r)>>1; if(pos<=mid) modify(ls[rt],l,mid,pos,val); else modify(rs[rt],mid+1,r,pos,val); } int query(int id,int val){ int now=root[id],ret=0; while(now){ if(tr[now].val==val) return ret+tr[tr[now].s[0]].size; else if(tr[now].val<val){ ret+=tr[tr[now].s[0]].size+tr[now].tag; now=tr[now].s[1]; } else now=tr[now].s[0]; } return ret; } int seq_queryrank(int rt,int l,int r,int a_l,int a_r,int val){ if(a_l<=l&&r<=a_r) return query(rt,val)-1; int ret=0,mid=(l+r)>>1; if(a_l<=mid) ret+=seq_queryrank(ls[rt],l,mid,a_l,a_r,val); if(mid<a_r) ret+=seq_queryrank(rs[rt],mid+1,r,a_l,a_r,val); return ret; } int querynumber(int l,int r,int k){ int L=0,R=oo,ret; while(L<=R){ int mid=(L+R)>>1; if(seq_queryrank(1,1,n,l,r,mid)+1<=k) ret=mid,L=mid+1; else R=mid-. 1 ; } return RET; } int findval ( int ID, int Val) { // find the value of x which int now = the root [ID]; the while ( . 1 ) { IF (TR [now] .val == Val ) return now; the else IF (TR [now] .val <Val) now TR = [now] .s [ . 1 ]; the else now TR = [now] .s [ 0 ]; } } int findrank ( int ID, int k) { // Find x which is ranked int now=root[id]; while(1){ if(tr[tr[now].s[0]].size>=k) {now=tr[now].s[0];continue;} k-=tr[tr[now].s[0]].size; if(k<=tr[now].tag) return now; k-=tr[now].tag; now=tr[now].s[1]; } } void dele(int id,int val){ int now=findval(id,val); splay(now,root[id],id); if(tr[now].tag>1) {tr[now].tag--;tr[now].size--;return ;} int k=tr[tr[now].s[0]].size,x=findrank(id,k),y=findrank(id,k+tr[now].tag+1); splay(x,root[id],id); splay(y,tr[x].s[1],id); tr[y].s[0]=0; update(y);update(x); } void get_dele(int rt,int l,int r,int pos,int val){ dele(rt,val); if(l==r) return ; int mid=(l+r)>>1; if(pos<=mid) get_dele(ls[rt],l,mid,pos,val); else get_dele(rs[rt],mid+1,r,pos,val); } int querypre(int id,int val){ int now=root[id],ans=-oo; while(now){ if(tr[now].val<val){ ans=max(ans,tr[now].val); now=tr[now].s[1]; } else now=tr[now].s[0]; } return ans; } int seg_querypre(int rt,int l,int r,int a_l,int a_r,int val){ if(a_l<=l&&r<=a_r) return querypre(rt,val); int ans=-oo,mid=(l+r)>>1; if(a_l<=mid) ans=max(ans,seg_querypre(ls[rt],l,mid,a_l,a_r,val)); if(mid<a_r) ans=max(ans,seg_querypre(rs[rt],mid+1,r,a_l,a_r,val)); return ans; } int querynext(int id,int val){ int now=root[id],ans=oo; while(now){ if(tr[now].val>val){ ans=min(ans,tr[now].val); now=tr[now].s[0]; } else now=tr[now].s[1]; } return ans; } int seg_querynext(int rt,int l,int r,int a_l,int a_r,int val){ if(a_l<=l&&r<=a_r) return querynext(rt,val); int ans=oo,mid=(l+r)>>1; if(a_l<=mid) ans=min(ans,seg_querynext(ls[rt],l,mid,a_l,a_r,val)); if(mid<a_r) ans=min(ans,seg_querynext(rs[rt],mid+1,r,a_l,a_r,val)); return ans; } void debug(int x){ if(tr[x].s[0]) debug(tr[x].s[0]);; printf("%d ",tr[x].val); if(tr[x].s[1]) debug(tr[x].s[1]); } int main(){ read(n);read(m); for(int i=1;i<=n;i++){ read(a[i]); modify(o,1,n,i,a[i]); } for(int i=1;i<=m;i++){ int opt;read(opt); if(opt==1){ int l,r,val; read(l);read(r);read(val); printf("%d\n",seq_queryrank(1,1,n,l,r,val)+1); } else if(opt==2){ int l,r,k; read(l);read(r);read(k); printf("%d\n",querynumber(l,r,k)); } else if(opt==3){ int pos,val; read(pos);read(val); get_dele(1,1,n,pos,a[pos]); modify(o,1,n,pos,a[pos]=val); } else if(opt==4){ int l,r,val; read(l);read(r);read(val); printf("%d\n",seg_querypre(1,1,n,l,r,val)); } else { int l,r,val; read(l);read(r);read(val); printf("%d\n",seg_querynext(1,1,n,l,r,val)); } } }