时间空间复杂度均为n*log^2,时间还好,空间简直爆炸。。。
#include #include #include #include #include #include #include #include #include #include #include #include #define MOD 1000000007 #define N 100005 using namespace std; typedef long long ll; int n,m,q,num,cnt,a[N],b[2*N],rt[N]; vector Ta,Tb; struct Tree { int ls,rs,sum; }tr[N*200]; struct Ask { int c,l,v,r,k; }ask[N]; void Insert_tree(int &node,int val,int x,int l,int r) { if(!node) node = ++cnt; tr[node].sum += x; if(l == r) return; int mid = (l+r)>>1; if(val <= mid) Insert_tree(tr[node].ls,val,x,l,mid); else Insert_tree(tr[node].rs,val,x,mid+1,r); } void Insert(int l,int val,int x) { while(l <= n) { Insert_tree(rt[l],val,x,1,m); l += l & (-l); } } void Find(int k,int ot) { if(!k) return; while(k) { if(ot == 1) Ta.push_back(rt[k]); else Tb.push_back(rt[k]); k -= k & (-k); } } int Query(int l,int r,int k) { Ta.clear(),Tb.clear(); Find(l-1,1),Find(r,2); int x = 1,y = m; while(x != y) { int a1 = 0,b1 = 0,mid = (x+y)>>1; for(int i = 0;i < Ta.size();i++) a1 += tr[tr[Ta[i]].ls].sum; for(int i = 0;i < Tb.size();i++) b1 += tr[tr[Tb[i]].ls].sum; num = b1 - a1; if(num >= k) { y = mid; for(int i= 0;i < Ta.size();i++) Ta[i] = tr[Ta[i]].ls; for(int i= 0;i < Tb.size();i++) Tb[i] = tr[Tb[i]].ls; } else { k -= num; x = mid+1; for(int i= 0;i < Ta.size();i++) Ta[i] = tr[Ta[i]].rs; for(int i= 0;i < Tb.size();i++) Tb[i] = tr[Tb[i]].rs; } } return b[x]; } int main() { while(~scanf("%d",&n)) { m = cnt = 0; memset(tr,0,sizeof(tr)); memset(rt,0,sizeof(rt)); for(int i = 1;i <= n;i++) { scanf("%d",&a[i]); b[++m] = a[i]; } scanf("%d",&q); for(int i = 1;i <= q;i++) { int c; scanf("%d",&c); ask[i].c = c; if(c == 1) { int l,v; scanf("%d%d",&l,&v); b[++m] = v; ask[i].l = l,ask[i].v = v; } else { int l,r,k; scanf("%d%d%d",&l,&r,&k); ask[i].l = l,ask[i].r = r,ask[i].k = k; } } sort(b+1,b+1+m); for(int i = 1;i <= n;i++) { int pos = lower_bound(b+1,b+1+m,a[i]) - b; Insert(i,pos,1); } for(int i = 1;i <= q;i++) { if(ask[i].c == 1) { int pos = lower_bound(b+1,b+1+m,a[ask[i].l]) - b; Insert(ask[i].l,pos,-1); a[ask[i].l] = ask[i].v; pos = lower_bound(b+1,b+1+m,a[ask[i].l]) - b; Insert(ask[i].l,pos,1); } else printf("%d\n",Query(ask[i].l,ask[i].r,ask[i].k)); } } }