1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
| // 더 많은 정보는 42jerrykim.github.io 에서 확인하세요.
#include <bits/stdc++.h>
using namespace std;
using int64 = long long;
static inline long long pow3(int n){
long long r = 1;
for(int i=0;i<n;i++) r *= 3LL;
return r;
}
static void gen_with_prune(
const vector<long long>& vals,
const vector<long long>& suffixAbs,
int idx,
long long cur,
long long otherAbsSum,
long long D,
vector<long long>& out
){
long long rem = suffixAbs[idx];
if (cur - rem > D + otherAbsSum) return;
if (cur + rem < -D - otherAbsSum) return;
if (idx == (int)vals.size()){
out.push_back(cur);
return;
}
gen_with_prune(vals, suffixAbs, idx+1, cur, otherAbsSum, D, out); // Lin
gen_with_prune(vals, suffixAbs, idx+1, cur + vals[idx], otherAbsSum, D, out); // Ad
gen_with_prune(vals, suffixAbs, idx+1, cur - vals[idx], otherAbsSum, D, out); // Larry
}
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int N;
if(!(cin >> N)) return 0;
vector<long long> A(N);
for(int i=0;i<N;i++) cin >> A[i];
long long D; cin >> D;
long long totalAbs = 0;
for(long long v: A) totalAbs += v;
if(D >= totalAbs){
cout << pow3(N) << '\n';
return 0;
}
sort(A.begin(), A.end(), [](long long x, long long y){
return llabs(x) > llabs(y);
});
int n1 = N/2;
int n2 = N - n1;
vector<long long> L(A.begin(), A.begin()+n1), R(A.begin()+n1, A.end());
long long sumAbsL = 0, sumAbsR = 0;
for(long long v: L) sumAbsL += llabs(v);
for(long long v: R) sumAbsR += llabs(v);
vector<long long> suffL(n1+1, 0), suffR(n2+1, 0);
for(int i=n1-1;i>=0;i--) suffL[i] = suffL[i+1] + llabs(L[i]);
for(int i=n2-1;i>=0;i--) suffR[i] = suffR[i+1] + llabs(R[i]);
size_t capL = 1, capR = 1;
for(int i=0;i<n1;i++) capL *= 3;
for(int i=0;i<n2;i++) capR *= 3;
vector<long long> S1; S1.reserve(capL);
vector<long long> S2; S2.reserve(capR);
gen_with_prune(L, suffL, 0, 0LL, sumAbsR, D, S1);
gen_with_prune(R, suffR, 0, 0LL, sumAbsL, D, S2);
sort(S2.begin(), S2.end());
long long ans = 0;
for(long long x: S1){
long long lo = -D - x;
long long hi = D - x;
auto itL = lower_bound(S2.begin(), S2.end(), lo);
auto itR = upper_bound(S2.begin(), S2.end(), hi);
ans += (long long)(itR - itL);
}
cout << ans << '\n';
return 0;
}
|