Question: sort the numbers in the interval in ascending order of the number of 1 in binary, and sort the numbers in ascending order of the same size. Calculates the number of K in the interval.
Http://www.spoj.pl/problems/SORTBIT/
For more information about the digital statistics, see the paper "Discussion on digital statistics".
First, you can enumerate the number of 1 based on what you learned in the previous question, then find the number of numbers containing several 1 in the interval, and finally obtain that the number of K contains several 1.
In this way, the answer contains Len 1.
Then, in the interval [l, r], find the number of Len 1 in [l, mid.
In case of any trouble, there are still negative numbers in the question. Negative Numbers are calculated based on their complement codes.
However, if the subject says positive and negative, there is no problem with positive and negative.
If the highest bit is 1, we first remove the 1 of the highest bit, and then convert it into a positive number. Then, we can add the highest bit to the output.
But pay attention to the case of 0, special sentence !!!
[Cpp]
# Include <iostream>
# Include <cstring>
# Include <queue>
# Include <cstdio>
# Include <cmath>
# Include <algorithm>
# Define N 30
# Define inf 1 <29
# Define MOD 2007.
# Define LL long
Using namespace std;
Int c [35] [35] = {0 };
// Count the number of k numbers containing 1 in [0, n]
Int slove (int n, int k ){
Int sum = 0, tot = 0;
For (int I = 31; I --){
If (n & (1 <I )){
Tot ++;
If (tot> k)
Break;
N ^ = (1 <I );
}
If (1 <(I-1) <= n)
Sum + = c [I-1] [k-tot];
}
If (tot + n = k) sum ++;
Return sum;
}
Int calc (int l, int r, int k ){
Int len = 1;
For (int I = 1; I <= 31; I ++ ){
Int now = slove (r, I)-slove (L-1, I );
If (k <= now) break;
K-= now;
Len = I + 1;
}
Int low = l, high = r, mid;
While (low // Second answer, and then find the number of [l, mid] containing len 1
Mid = (int) (LL) low + (LL) high)/2 );
Int now = slove (mid, len)-slove (L-1, len );
If (now <k)
Low = mid + 1;
Else
High = mid;
}
Return low;
}
Int main (){
Int t, l, r, k;
For (int I = 0; I <= 32; I ++ ){
C [I] [0] = c [I] [I] = 1;
For (int j = 1; j <I; j ++)
C [I] [j] = c [I-1] [J-1] + c [I-1] [j];
}
Scanf ("% d", & t );
While (t --){
Scanf ("% d", & l, & r, & k );
If (l = 0 & r = 0 ){
Printf ("0 \ n ");
Continue;
}
If (l> = 0 & r> = 0 ){
If (l = 0 ){
K --;
L = 1;
}
If (k = 0 ){
Printf ("0 \ n ");
Continue;
}
Printf ("% d \ n", calc (l, r, k ));
}
Else {
If (r = 0 ){
K --;
R =-1;
}
// Remove the highest bit
L & = (~ (1 <31 ));
R & = (~ (1 <31 ));
Cout <l <"" <r <endl;
Printf ("% d \ n", (1 <31) | calc (l, r, k ));
}
}
Return 0;
}
By ACM_cxlove