-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathTwoSets2.cpp
More file actions
136 lines (128 loc) · 3.05 KB
/
TwoSets2.cpp
File metadata and controls
136 lines (128 loc) · 3.05 KB
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
//Two Sets II - https://cses.fi/problemset/task/1093
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MOD = 1e9 + 7;
const ll INF = 1e18;
template<class T>
constexpr T power(T a, ll b) {
T res = 1;
while (b > 0) {
if (b & 1) {
res *= a;
}
a *= a;
b >>= 1;
}
return res;
}
template<int P>
struct MInt {
int x;
constexpr MInt() : x{} {}
constexpr MInt(ll x) : x{norm(x % P)} {}
constexpr int norm(int z) const {
if (z < 0) {
z += P;
}
if (z >= P) {
z -= P;
}
return z;
}
constexpr int val() const {
return x;
}
explicit constexpr operator int() const {
return x;
}
constexpr MInt operator-() const {
MInt res;
res.x = norm(P - x);
return res;
}
constexpr MInt inv() const {
assert(x != 0);
return power(*this, P - 2);
}
constexpr MInt &operator*=(MInt rhs) {
x = 1LL * x * rhs.x % P;
return *this;
}
constexpr MInt &operator+=(MInt rhs) {
x = norm(x + rhs.x);
return *this;
}
constexpr MInt &operator-=(MInt rhs) {
x = norm(x - rhs.x);
return *this;
}
constexpr MInt &operator/=(MInt rhs) {
return *this *= rhs.inv();
}
friend constexpr MInt operator*(MInt lhs, MInt rhs) {
MInt res = lhs;
res *= rhs;
return res;
}
friend constexpr MInt operator+(MInt lhs, MInt rhs) {
MInt res = lhs;
res += rhs;
return res;
}
friend constexpr MInt operator-(MInt lhs, MInt rhs) {
MInt res = lhs;
res -= rhs;
return res;
}
friend constexpr MInt operator/(MInt lhs, MInt rhs) {
MInt res = lhs;
res /= rhs;
return res;
}
friend constexpr std::istream &operator>>(std::istream &is, MInt &a) {
ll v;
is >> v;
a = MInt(v);
return is;
}
friend constexpr std::ostream &operator<<(std::ostream &os, const MInt &a) {
return os << a.val();
}
friend constexpr bool operator==(MInt lhs, MInt rhs) {
return lhs.val() == rhs.val();
}
friend constexpr bool operator!=(MInt lhs, MInt rhs) {
return lhs.val() != rhs.val();
}
};
template<int V, int P>
constexpr MInt<P> CInv = MInt<P>(V).inv();
constexpr int P = MOD;
using Mint = MInt<P>;
void solve() {
int n;
cin >> n;
int s = n * (n + 1) / 2;
vector<vector<Mint>> dp(n + 2, vector<Mint>(2*s + 2, -1));
auto dfs = [&](auto dfs, int cur, int sum) -> Mint {
if (cur == n + 1) {
return sum == 0;
}
if (dp[cur][s + sum] != -1) {
return dp[cur][s + sum];
}
return dp[cur][s + sum] = dfs(dfs, cur + 1, sum - cur) + dfs(dfs, cur + 1, sum + cur);
};
cout << dfs(dfs, 1, 0) / 2 << endl;
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
int T = 1;
// cin >> T;
while (T--) {
solve();
}
return 0;
}