#pragma comment(linker, "/STACK:102400000,102400000") #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <set> #include <vector> #include <map> #include <queue> #include <set> #include <algorithm> #include <limits> #include <time.h> using namespace std; typedef long long LL; const int MAXN=1e+5 + 1000; const int INF = numeric_limits<int>::max(); const LL LL_INF= numeric_limits<LL>::max(); struct SBT { int left,right,size,key; void Init() { left=right=0; size=1; } }tree[MAXN*30]; int tot,root[MAXN<<2],n; void left_rotate(int &x) { int y=tree[x].right; tree[x].right=tree[y].left; tree[y].left=x; tree[y].size=tree[x].size; tree[x].size=tree[tree[x].left].size+tree[tree[x].right].size+1; x=y; } void right_rotate(int &x) { int y=tree[x].left; tree[x].left=tree[y].right; tree[y].right=x; tree[y].size=tree[x].size; tree[x].size=tree[tree[x].left].size+tree[tree[x].right].size+1; x=y; } void maintain(int &x,int flag) { if(flag==0) { if(tree[tree[tree[x].left].left].size > tree[tree[x].right].size) right_rotate(x); else if(tree[tree[tree[x].left].right].size > tree[tree[x].right].size) left_rotate(tree[x].left),right_rotate(x); else return; } else { if(tree[tree[tree[x].right].right].size > tree[tree[x].left].size) left_rotate(x); else if(tree[tree[tree[x].right].left].size > tree[tree[x].left].size) right_rotate(tree[x].right),left_rotate(x); else return; } maintain(tree[x].left,0); maintain(tree[x].right,1); maintain(x,0); maintain(x,1); }
void insert(int &x,int key) { if(x==0) { x=++tot; tree[x].Init(); tree[x].key=key; } else { tree[x].size++; if(key<tree[x].key)insert(tree[x].left,key); else insert(tree[x].right,key); maintain(x,key>=tree[x].key); } }
int del(int &x,int key) { if(!x)return 0; tree[x].size--; if(key==tree[x].key || (key<tree[x].key&&tree[x].left==0) || (key>tree[x].key&&tree[x].right==0)) { if(tree[x].left && tree[x].right) { int p=del(tree[x].left,key+1); tree[x].key=tree[p].key; return p; } else { int p=x; x=tree[x].left+tree[x].right; return p; } } else return del(key<tree[x].key?tree[x].left:tree[x].right,key); } int _rank(int x,int val){ if(x==0)return 0; if(tree[x].key<=val)return tree[tree[x].left].size+1+_rank(tree[x].right,val); return _rank(tree[x].left,val); } void print(int x,int d){ if(!x)return ; printf("%d %d\n",tree[x].key,d); print(tree[x].left,d+1);print(tree[x].right,d+1); } int A[MAXN]; void Add(int x,int v){ while(x<=n){ insert(root[x],v); x+=x&-x; } } void Del(int x,int v){ while(x<=n){ del(root[x],v); x+=x&-x; } } int Sum(int x,int v){ int cnt=0; while(x>0){ cnt+=_rank(root[x],v); x-=x&-x; } return cnt; } struct Q { int type,l,r,v; }cs[MAXN]; int res[MAXN*2]; int main() { int q; while(~scanf("%d",&n)){ memset(root,0,sizeof(root)); tot=0; res[0]=0; for(int i=1;i<=n;i++)scanf("%d",&A[i]),res[++res[0]]=A[i]; scanf("%d",&q); for(int i=0;i<q;i++){ scanf("%d",&cs[i].type); if(cs[i].type==1){ scanf("%d%d",&cs[i].l,&cs[i].v); res[++res[0]]=cs[i].v; } else { scanf("%d%d%d",&cs[i].l,&cs[i].r,&cs[i].v); } } sort(res+1,res+1+res[0]); res[0]=unique(res+1,res+1+res[0])-res-1; for(int i=0;i<q;i++){ if(cs[i].type==1){ cs[i].v=lower_bound(res+1,res+1+res[0],cs[i].v)-res; } } for(int i=1;i<=n;i++)A[i]=lower_bound(res+1,res+1+res[0],A[i])-res; for(int i=1;i<=n;i++){ Add(i,A[i]); } for(int i=0;i<q;i++){ if(cs[i].type==1){ Del(cs[i].l,A[cs[i].l]); Add(cs[i].l,cs[i].v); A[cs[i].l]=cs[i].v; } else { int l=1,r=res[0],ans=res[0]; while(l<=r){ int mid=(l+r)>>1; int t=Sum(cs[i].r,mid)-Sum(cs[i].l-1,mid); if(t>=cs[i].v){ ans=mid; r=mid-1; } else l=mid+1; } printf("%d\n",res[ans]); } } } return 0; }
|