import
java.util.ArrayList;
import
java.util.Arrays;
import
java.util.List;
import
java.util.Scanner;
import
java.util.function.BiPredicate;
public
class
Main
{
private
static
void
generateSubsetSumsRecur(
int
[] arr,
int
st,
int
end,
int
index,
int
runningSum, List<Integer> sums) {
if
(index == end+
1
) {
sums.add(runningSum);
return
;
}
generateSubsetSumsRecur(arr, st, end, index+
1
, runningSum+arr[index], sums);
generateSubsetSumsRecur(arr, st, end, index+
1
, runningSum, sums);
}
private
static
long
numberOfSubsets(
int
arr[],
int
n,
int
a,
int
b) {
List<Integer> sums =
new
ArrayList<>();
generateSubsetSumsRecur(arr,
0
, n/
2
,
0
,
0
, sums);
Integer[] firstSubsetSums= sums.toArray(
new
Integer[
0
]);
List<Integer> sums2 =
new
ArrayList<>();
generateSubsetSumsRecur(arr, n/
2
+
1
, n-
1
, n/
2
+
1
,
0
, sums2);
Integer[] secondSubsetSums= sums2.toArray(
new
Integer[
0
]);
Arrays.sort(secondSubsetSums);
long
count =
0
;
for
(
int
i=
0
; i<firstSubsetSums.length; i++) {
int
p = findLastIdxWithFalsePredicate(secondSubsetSums,
a-firstSubsetSums[i],
(sum, mark)->sum>=mark);
int
q = findLastIdxWithFalsePredicate(secondSubsetSums,
b-firstSubsetSums[i],
(sum, mark)->sum>mark);
count += (q-p);
}
return
count;
}
private
static
int
findLastIdxWithFalsePredicate(Integer[] sums,
int
val,
BiPredicate<Integer, Integer> pred) {
int
min =
0
;
int
max = sums.length-
1
;
while
(min<max) {
int
mid = min + (max-min+
1
)/
2
;
if
(pred.test(sums[mid], val)) {
max = mid-
1
;
}
else
{
min = mid;
}
}
if
(pred.test(sums[min], val))
return
-
1
;
return
min;
}
public
static
void
main(String args[])
{
int
N =
3
;
int
A = -
1
;
int
B =
2
;
int
arr[] = {
1
, -
2
,
3
};
System.out.println(numberOfSubsets(arr, N, A, B));
}
}