-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathcombinatorics.h
57 lines (50 loc) · 1.3 KB
/
combinatorics.h
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
/*
* combinatorics header
* written by Shuangquan Li, [email protected]
* created on 2016-7-10
* last edit on 2016-7-16
*/
#ifndef __COMBINATORICS_H__
#define __COMBINATORICS_H__
#include <vector>
// permutations of 1,2,...,N-1
// permutation id is 0,1,2,...,(N!-1)
// function to calc i!
inline long long fact(int i) {
static std::vector<long long> dp;
if (dp.size() > i) return dp[i];
if (dp.empty()) dp.push_back(1);
while (dp.size() <= i) dp.push_back(dp.back() * dp.size());
return dp[i];
}
// to calc permutation id of a permutation of 1,2,...,N
inline long long Cantor(const std::vector<int>& a) {
long long ret = 0;
for (int i = 0; i < a.size(); ++i) {
int tp = 0;
for (int j = i + 1; j < a.size(); ++j)
if (a[j] < a[i]) ++tp;
ret += tp * fact(a.size() - i - 1);
}
return ret;
}
// to calc a permutation of 1,2,...,N whose permutation id is id
inline std::vector<int> unCantor(int N, long long id) {
std::vector<int> ret(N);
std::vector<bool> used(N + 1, false);
for (int i = 1; i < N + 1; ++i) {
long long a = id / fact(N - i);
id %= fact(N - i);
int cnt = 0;
for (int j = 1; j < N + 1; ++j) if (!used[j]) {
if (++cnt == a + 1) {
ret[i - 1] = j;
used[j] = true;
break;
}
}
}
return ret;
}
/* eof */
#endif