Topic links: https://www.luogu.org/problemnew/show/P2617
topic:
Title Description
Given a sequence comprising n number of a [1], a [2], [3] ...... a [n] a, must answer the inquiry procedure: for a given i, j, k, in a [ i], a [i + 1], a [i + 2] ...... a [j] in the k-th smaller number is the number (1≤k≤j-i + 1), and you can change the number of a [ i] value, after the change, the program can continue to answer the above questions for a later change. You need to compile such a program, a sequence of reads from the input file, and reads the series of instructions, including instructions and a modification instruction interrogation.
For each query command, you must output the correct answer.
Input and output formats
Input formats:
The first line has two positive integers n (1≤n≤100000), m (1≤m≤100000). Respectively represent the number and length of the instruction sequence.
The second row has the number n, represents a [1], a [2] ...... a [n], these numbers are less than 10 ^ 9. The following description of each instruction m rows, each row format is one of two formats. Q ijk or C it
-
Q ijk (i, j, k is a number, 1≤i≤j≤n, 1≤k≤j-i + 1) represents inquiry command to inquire about a [i], a [i + 1] ...... a [j the number of small k] in.
-
C (1≤i≤n, 0≤t≤10 ^ 9) represents the a [i] becomes changed t.
Output formats:
For each prompt, you need to answer his output, each output on separate lines.
Sample input and output
5 3 3 2 1 4 7 Q 1 4 3 C 2 6 Q 2 5 3
3 6 problem-solving ideas: Dynamic template Chairman tree problem, mainly used Fenwick tree sets Chairman of the tree, and change the prefix handling various weights tree line static Chairman of the tree, where the use of prefixes and handling Fenwick tree in balance the time and space and modify the query. Time and space complexity is O ( n- L O G n- L O G n- ) O (nlognlogn). Code:
#include<iostream> #include<cstdio> #include<cstring> #include<vector> #include<algorithm> using namespace std; typedef long long ll; const int maxn=100005; struct node{ int l,r,sum; }tree[maxn*600]; //数组开nlog n的大小 struct Q{ int a,b,c; }q[maxn]; int n,m,cnt,sz,a[maxn],root[maxn*600],num1,num2,L[maxn],R[maxn]; vector<int> v; int getid(int x){ return lower_bound(v.begin(),v.end(),x)-v.begin()+1; } int lowbit(int x){ return x&(-x); } void update(int &x,int y,int l,int r,int pos,int val){ tree[++cnt]=tree[y],tree[cnt].sum+=val,x=cnt; if(l==r) return; int mid=(l+r)/2; if(mid>=pos) update(tree[x].l,tree[y].l,l,mid,pos,val); else update(tree[x].r,tree[y].r,mid+1,r,pos,val); } void add(int x,int val){ //树状数组维护前缀和 int pos=getid(a[x]); for(int i=x;i<=n;i+=lowbit(i)) update(root[i],root[i],1,sz,pos,val); } int query(int l,int r,int k){ if(l==r) return l; int mid=(l+r)/2,sum=0; for(int i=1;i<=num1;i++) sum-=tree[tree[L[i]].l].sum; for(int i=1;i<=num2;i++)sum+=tree[tree[R[i]].l].sum; if(sum>=k){ for(int i=1;i<=num1;i++) L[i]=tree[L[i]].l; for(int i=1;i<=num2;i++) R[i]=tree[R[i]].l; return query(l,mid,k); }else{ for(int i=1;i<=num1;i++) L[i]=tree[L[i]].r; for(int i=1;i<=num2;i++) R[i]=tree[R[i]].r; return query(mid+1,r,k-sum); } } int main(){ char s[10]; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d",&a[i]),v.push_back(a[i]); for(int i=1;i<=m;i++){ scanf("%s",s); scanf("%d%d",&q[i].a,&q[i].b); if(s[0]=='Q'){ scanf("%d",&q[i].c); }else{ q[i].c=0; v.push_back(q[i].b); } } sort(v.begin(),v.end()); v.erase(unique(v.begin(),v.end()),v.end()); sz=v.size(); for ( int I = . 1 ; I <= n-; I ++) the Add (I, . 1 ); for ( int I = . 1 ; I <= m; I ++ ) { IF (Q [I] .c) { num1 = 0 , = num2 0 ; for ( int J = Q [I] .a- . 1 ; J; = J-lowbit (J)) L [num1 ++] = the root [J]; // line segments tree stored to be operated for ( int J = Q [I] .B; J; = J-lowbit (J)) R & lt [num2 ++] = the root [J]; the printf ( " % D \ n- " , V [Query ( . 1 , SZ , Q [I] .c) - . 1]); }else { add(q[i].a,-1); a[q[i].a]=q[i].b; add(q[i].a,1); } } return 0; }