Topic links: http://acm.hdu.edu.cn/showproblem.php?pid=6621
Meaning of the questions: to an array, repeatedly asked l, r, k, p, l ~ r asked a small section of the first k | p-ai | How much is
1 <= p, ai <1e6 , 1 <= K <= 169 , R - L + 1> = K, 1 <= n, m <= 10 ^ 5
Solution: binary answer + President tree
-half the absolute value of the answer r, then President tree search [pr, p + r] interval how many number of, if more than equal to k th reduced r and record answers less than the k r increases
a case is r satisfy the k, but the r answer does not exist at this time would be half the smaller r, until accurate to the r presence of
the President of tree maintenance total number of the current node l ~ r value range of a few more
Official explanations
Using segment tree, we can find the number of values smaller than p in [L, R] within O(log(n)).
So by using binary search method, we can find the answer in O(log(n)^2) time.
Total time complexity is O(N log(N) + Q log(N)^2).
AC Code:
. 1 #include <bits / STDC ++ H.> 2 the using namespace STD; . 3 typedef Long Long LL; . 4 int const MAXN = 1E5 + 100 , maxn2 = 1e6 + 10 ; . 5 int m, n-, Q, A [MAXN], TOT, Froot [MAXN], C [maxn2 * 30 ], LSON [maxn2 * 30 ], rson [maxn2 * 30 ]; // 40-fold open space Chairman tree n typically enough . 6 . 7 int Update ( int the root, int POS, int Val) { // after the addition of a new value of the new tree, root of a tree before . 8 intthe newroot = TOT ++, tmp = the newroot; . 9 C [the newroot] = C [the root] + Val; // node value of the new tree = previous value of the tree + newly added 10 int L = . 1 , R & lt = 1e6; . 11 the while (L < R & lt) { 12 is int MID = (L + R & lt) >> . 1 ; 13 is IF (POS <= MID) { // See modified value is the sub-tree which pieces 14 LSON [the newroot] TOT = ++; rson [ the newroot] = rson [the root]; // if in the left subtree, then the value of the right subtree of the original tree can use 15 the newroot LSON = [the newroot]; = the root LSON [the root]; 16 R & lt = MID; . 17 } 18 the else{ . 19 rson [the newroot] = TOT ++; LSON [the newroot] = LSON [the root]; 20 is [the newroot] the newroot = rson; the root = rson [the root]; 21 is L = MID + . 1 ; 22 is } 23 is C [the newroot] = C [ the root] + Val; 24 } 25 return tmp; // root node of the new tree 26 is } 27 int Query ( int L, int R & lt, int K, int LR, int RR) { 28 // current point l, r in time tree numbers were No. LR, rr, 29 //The current point control interval [l, r], to query interval [. 1, K] 30 IF (K> = R & lt) return C [RR] - C [LR]; 31 is int MID = (L + R & lt) >> . 1 , ANS = 0 ; 32 IF ( . 1 <= MID) ANS + = Query (L, MID, K, LSON [LR], LSON [RR]); 33 is IF (K> MID) ANS + = Query (MID + . 1 , R & lt , K, rson [LR], rson [RR]); 34 is return ANS; 35 } 36 int query_node ( int LR, int RR, int P, int K) { // a maintenance segment tree number 37 [ int= L 0 , R & lt = 1e6, MID, ANS, Al, Ar, GG; // a radius of half of the absolute value of the answer | P-AI | 38 is the while (L <= R & lt) { 39 MID = (L + R & lt) >> . 1 ; 40 Al = MID-P, P + Ar = MID; // look al - ar number section number, if <k a, the radius to be increased, if <= k a radius might be possible It needs to be reduced (because of the current assigned number may not exist), but the answer must be a little too big small can not. 41 is IF (Al <= . 1 ) GG = Query ( . 1 , 1e6, Ar, Froot [LR], Froot [RR]); // if al <0, 0 ~ ar to see how much the number 42 is the else GG = Query ( . 1 , 1e6, Ar, Froot [LR], Froot [RR]) - Query ( . 1 , 1e6, Al- . 1 , Froot [LR], Froot [RR]); 43 is IF(gg>=k){ 44 ans=mid;r=mid-1; 45 } 46 else l=mid+1; 47 } 48 return ans; 49 } 50 int build(int l,int r){//初始建树 51 int root=tot++; 52 c[root]=0; 53 if(l!=r){ 54 int mid=(l+r)>>1; 55 lson[root]=build(l,mid); 56 rson[root]=build(mid+1,r); 57 } 58 return root; 59 } 60 inline int get_num(){ 61 char ch; 62 bool flag=false; 63 int num=0; 64 ch=getchar(); 65 while(ch<'0'||ch>'9'){if(ch=='-')flag=true;ch=getchar();} 66 while(ch>='0'&&ch<='9'){num=(num<<3)+(num<<1)+ch-'0';ch=getchar();} 67 if(flag)return -1*num; 68 return num; 69 } 70 int main(){ 71 int T,ans; 72 scanf("%d",&T); 73 while(T--){ 74 scanf("%d%d",&n,&q); 75 tot=0,ans=0; 76 for(int i=1;i<=n;i++){ 77 a[i]=get_num(); 78 } 79 80 froot[0]= build(1,1e6); 81 for(int i=1;i<=n;i++){ 82 froot[i]=update(froot[i-1],a[i],1); 83 } 84 while(q--){ 85 int l,r,p,k; 86 l=get_num()^ans,r=get_num()^ans,p=get_num()^ans,k=get_num()^ans; 87 ans=query_node(l-1,r,p,k); 88 printf("%d\n",ans); 89 } 90 } 91 92 return 0; 93 }