[Hdu-6621] K-th Closest Distance Chairman tree tree line over 2019 school 4

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 }

 

Guess you like

Origin www.cnblogs.com/conver/p/11286918.html