Skip to content

Commit 4c1d89e

Browse files
author
atcoder-live
committed
combination, lca, mod division
1 parent 3cf86e5 commit 4c1d89e

File tree

3 files changed

+106
-2
lines changed

3 files changed

+106
-2
lines changed

comb.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
[mint]
2+
// combination mod prime
3+
// https://www.youtube.com/watch?v=8uowVvQ_-Mo&feature=youtu.be&t=1619
4+
struct combination {
5+
vector<mint> fact, ifact;
6+
combination(int n):fact(n+1),ifact(n+1) {
7+
fact[0] = 1;
8+
for (int i = 1; i <= n; ++i) fact[i] = fact[i-1]*i;
9+
ifact[n] = fact[n].inv();
10+
for (int i = n; i >= 1; --i) ifact[i-1] = ifact[i]*i;
11+
}
12+
mint operator()(int n, int k) {
13+
if (k < 0 || k > n) return 0;
14+
return fact[n]*ifact[k]*ifact[n-k];
15+
}
16+
};

lca.cpp

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
// Lowest Common Ancestor by binary lifting
2+
// https://youtu.be/8uowVvQ_-Mo?t=4306
3+
template<typename T> // T: type of cost
4+
struct lca {
5+
int n, root, l;
6+
vector<vector<int>> to;
7+
vector<vector<T>> co;
8+
vector<int> dep;
9+
vector<T> costs;
10+
vector<vector<int>> par;
11+
lca(int n):n(n),to(n),co(n),dep(n),costs(n) {
12+
l = 0;
13+
while ((1<<l) < n) ++l;
14+
par = vector<vector<int>>(n+1,vector<int>(l,n));
15+
}
16+
void addEdge(int a, int b, T c=0) {
17+
to[a].push_back(b); co[a].push_back(c);
18+
to[b].push_back(a); co[b].push_back(c);
19+
}
20+
void dfs(int v, int d=0, T c=0, int p=-1) {
21+
if (p != -1) par[v][0] = p;
22+
dep[v] = d;
23+
costs[v] = c;
24+
for (int i = 0; i < to[v].size(); ++i) {
25+
int u = to[v][i];
26+
if (u == p) continue;
27+
dfs(u, d+1, c+co[v][i], v);
28+
}
29+
}
30+
31+
void init(int _root=0) {
32+
root = _root;
33+
dfs(root);
34+
for (int i = 0; i < l-1; ++i) {
35+
for (int v = 0; v < n; ++v) {
36+
par[v][i+1] = par[par[v][i]][i];
37+
}
38+
}
39+
}
40+
// LCA
41+
int operator()(int a, int b) {
42+
if (dep[a] > dep[b]) swap(a,b);
43+
int gap = dep[b]-dep[a];
44+
for (int i = l-1; i >= 0; --i) {
45+
int len = 1<<i;
46+
if (gap >= len) {
47+
gap -= len;
48+
b = par[b][i];
49+
}
50+
}
51+
if (a == b) return a;
52+
for (int i = l-1; i >= 0; --i) {
53+
int na = par[a][i];
54+
int nb = par[b][i];
55+
if (na != nb) a = na, b = nb;
56+
}
57+
return par[a][0];
58+
}
59+
int length(int a, int b) {
60+
int c = lca(a,b);
61+
return dep[a]+dep[b]-dep[c]*2;
62+
}
63+
T dist(int a, int b) {
64+
int c = lca(a,b);
65+
return costs[a]+costs[b]-costs[c]*2;
66+
}
67+
};

mint.cpp

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
// auto mod int
12
// https://youtu.be/L8grWxBlIZ4?t=9858
2-
// https://youtu.be/ERZuLAxZffQ?t=4765
3+
// https://youtu.be/ERZuLAxZffQ?t=4807 : optimize
4+
// https://youtu.be/8uowVvQ_-Mo?t=1329 : division
35
const int mod = 1000000007;
46
struct mint {
5-
ll x;
7+
ll x; // typedef long long ll;
68
mint(ll x=0):x(x%mod){}
79
mint& operator+=(const mint a) {
810
if ((x += a.x) >= mod) x -= mod;
@@ -28,4 +30,23 @@ struct mint {
2830
mint res(*this);
2931
return res*=a;
3032
}
33+
mint pow(ll t) const {
34+
if (!t) return 1;
35+
mint a = pow(t>>1);
36+
a *= a;
37+
if (t&1) a *= *this;
38+
return a;
39+
}
40+
41+
// for prime mod
42+
mint inv() const {
43+
return pow(mod-2);
44+
}
45+
mint& operator/=(const mint a) {
46+
return (*this) *= a.inv();
47+
}
48+
mint operator/(const mint a) const {
49+
mint res(*this);
50+
return res/=a;
51+
}
3152
};

0 commit comments

Comments
 (0)