CRB and Queries Time limit:12000/6000 MS (java/others) Memory limit:131072/131072 K (java/others)
Total submission (s): 636 Accepted Submission (s): 162
Problem Description There is N boys in Codeland.
Boy I have his coding skill Ai.
CRB wants to know who has the suitable coding skill.
So you should treat the following and the types of queries.
Query 1:1 L V
The coding skill of boy L have changed to V.
Query 2:2 l R k
This was a report query which asks the k-th smallest value of coding skill between boy L and boy R (both inclusive).
Input There is multiple test cases.
The first line contains a single integer N.
Next line contains N space separated integers A1, A2, ..., an, where Ai denotes initial coding skill of the boy I.
Next line contains a single integer Q representing the number of queries.
Next Q lines contain queries which can be any of the and the both types.
1≤n, q≤105
1≤ai, v≤109
1≤l≤r≤n
1≤k≤r–l + 1
Output for each query of type 2, output a single integer corresponding to the answer with a single line.
Sample Input
5 1 2 3 4 5 3 2 2 4 2 1 3 6 2 2 4 2
Sample Output
3 4
Author KUT (DPRK)
Source multi-university Training Contest 10
Ask for the interval k large number, http://www.cnblogs.com/zig-zag/archive/2013/04/18/3027707.html reference this blog, and then see 2013 years Training Team XHR thesis. It
Solution: The operation is divided into three kinds,
1. Add a number,
2. Delete a number,
3. Ask the answer in the left or the interval
Method:
What is the answer to the two-point question?
For an initial number, becomes an insert operation
Arrange actions in chronological order of operations, split for delete and join operations for modify operations
: 1 Delete the number that was inserted before, 2. Add a new number
Next divide the answer to two points:
For mid, if the insertion or deletion of the number <=mid then should be placed in the left interval, and with a tree-like array (other data structure also line)
How many numbers are on the left for the first X positions of maintenance.
For inquiries: If the L,r interval is on the left of the number >=k then the answer is on the left, otherwise the answer is on the right, and the number of digits to the left is updated k,k=k-this interval
When low =high, it means that low is the answer, as long as the update inquiry is still in the low,low between the answer can be.
Complexity analysis: The depth of division is that log (s) s is the range of data.
Each query is divided to the left or right, and there is a log (s) operation. Each insert or delete is also.
But to maintain the number of numbers in a tree array on the left, log (n) updates or queries.
Complexity is N*log (s) *log (n)
#include <iostream> #include <cstring> #include <algorithm> #include <cstdio> #include <
Vector> using namespace std;
#define MAXN 300007 int TREE[MAXN];
void Add (int p,int n) {for (;p <maxn;p+=p& (-P)) tree[p]+=n;} int query (int p) {int ans = 0;
For (;p >0;p-=p& (-P)) ans + = tree[p];
return ans;
} struct node{int l,r,k,ty,ans;};
Node P[MAXN];
int ID1[MAXN],ID2[MAXN];
void CDQ (int l,int r,int Low,int high) {if (R < L) return; if (low = = high) {for (; l<=r;
l++) {P[id1[l]].ans = low;
} return;
} int mid = (Low+high)/2,l=l,r=r,k,u;
for (int i = L;i <= R; i++) {u = id1[i];
if (p[u].ty = = 2) {k = query (P[U].R)-Query (P[U].L-1);
if (k >= p[u].k) id2[l++] = u;
else {p[u].k-= k;
id2[r--] = u; }} else if (P[U].K <= mid) {Add (p[u].l,p[U].ty);
id2[l++] = u;
} else id2[r--] = u;
} for (int i = L; I <= R; i++) {u = id1[i];
if (p[u].ty! = 2 && p[u].k <= mid) Add (p[u].l,-p[u].ty);
} for (k=l;k<l;k++) id1[k] = id2[k];
for (r=r;k<=r;k++) id1[k] = id2[r--];
CDQ (L,l-1,low,mid);
CDQ (L,r,mid+1,high);
} int NUM[MAXN];
int main () {int n,q,t,cnt;
memset (tree,0,sizeof (tree));
while (scanf ("%d", &n)!=eof) {for (cnt=0;cnt<n;cnt++) {scanf ("%d", &P[CNT].K);
P[cnt].ty = 1;
P[CNT].L = cnt+1;
NUM[CNT+1] = P[CNT].K;
} scanf ("%d", &q);
int ty,l,v;
for (int i = 0;i < Q; i++,cnt++) {scanf ("%d", &p[cnt].ty);
if (p[cnt].ty = = 1) {scanf ("%d%d", &l,&v);
P[cnt].ty =-1;
P[CNT].K = Num[l];
P[CNT].L = l;
cnt++; Num[l] = v;
P[cnt].ty = 1;
P[CNT].K = v;
P[CNT].L = l;
} else {scanf ("%d%d%d", &P[CNT].L,&P[CNT].R,&P[CNT].K);
}} for (int i = 0;i < cnt; i++) id1[i] = i;
CDQ (0,cnt-1,0,1000000000);
for (int i = 0;i < cnt; i++) {if (p[i].ty = = 2) printf ("%d\n", P[i].ans);
}} return 0;
}