├── .gitignore ├── .travis.yml ├── DataStructure ├── BinaryIndexedTree │ ├── BIT.cpp │ ├── BIT.rs │ ├── README.md │ └── t │ │ └── BITGTest.cc ├── DisjointSet │ ├── DisjointSet.cpp │ ├── DisjointSet.rs │ ├── ExtDisjointSet.cpp │ ├── ExtDisjointSet.rs │ ├── README.md │ └── t │ │ ├── DisjointSetGTest.cc │ │ ├── ExtDisjointSetGTest.cc │ │ └── GTestHelper.cpp ├── RangeMinimumQuery │ ├── README.md │ ├── RMQ.cpp │ ├── RMQ.hs │ ├── RMQ.rs │ └── t │ │ └── RMQGTest.cc └── SegmentTree │ ├── README.md │ └── SegmentTree.rs ├── Graph ├── Connectivity │ ├── BiconnectedComponents │ │ ├── BridgeBlockTree.cpp │ │ ├── README.md │ │ ├── Tarjan.cpp │ │ └── t │ │ │ └── TarjanGTest.cc │ └── StrongComponents │ │ ├── Kosaraju.cpp │ │ ├── Tarjan.cpp │ │ └── t │ │ ├── GTestHelper.cpp │ │ ├── KosarajuGTest.cc │ │ └── TarjanGTest.cc ├── FlowNetwork │ └── MinCostMaxFlow │ │ ├── MinCostMaxFlow.cpp │ │ ├── README.md │ │ └── UnitMinCostMaxFlow.cpp └── Matching │ ├── BipartiteMatching │ ├── HopcroftKarp.cpp │ ├── Hungarian.cpp │ └── t │ │ ├── GTestHelper.cpp │ │ ├── HopcroftKarpGTest.cc │ │ └── HungarianGTest.cc │ ├── GeneralMatching │ ├── EdmondsBlossom.rs │ └── README.md │ └── README.md ├── NumberTheory ├── Matrix │ ├── Matrix.cpp │ └── README.md ├── ModInverse │ ├── ModInverse.cpp │ ├── ModInverse.hs │ └── ModInverse.rs ├── ModLinear │ └── ModLinear.java ├── Modulo │ ├── MInt.hs │ └── MInt.rs ├── NumberTheoreticTransform │ ├── NTT.rs │ └── README.md ├── Prime │ ├── MillerRabin.hs │ ├── PrimeTable.cpp │ └── PrimeTable.rs └── Ring │ ├── README.md │ └── Ring.cpp ├── Numeric ├── FastFourierTransform │ ├── FFT.hs │ └── README.md └── LinearSystem │ └── GaussLU.cpp ├── README.md ├── Rakefile ├── String ├── AhoCorasick │ ├── AhoCorasick.cpp │ └── README.md ├── Matching │ ├── KMP.cpp │ ├── KMP.hs │ ├── README.md │ ├── Z.cpp │ └── t │ │ ├── KMPGTest.cc │ │ └── ZGTest.cc ├── Palindrome │ ├── Manacher.cpp │ ├── Manacher.hs │ ├── README.md │ └── t │ │ └── ManacherGTest.cc ├── Suffix │ ├── README.md │ ├── SuffixArrayBase.cpp │ ├── SuffixArrayNaive.cpp │ ├── SuffixArraySimple.cpp │ ├── SuffixArrayYoung.cpp │ └── t │ │ ├── BenchmarkGTest.cc │ │ ├── GTestHelper.cpp │ │ ├── SuffixArraySimpleGTest.cc │ │ └── SuffixArrayYoungGTest.cc └── t │ └── GTestHelper.cpp ├── Tree ├── HeavyLightDecomposition │ ├── HeavyLightDecomposition.cpp │ ├── HeavyLightDecomposition.rs │ └── README.md ├── LCA │ ├── LCA.cpp │ └── prob └── WeightedPathLength │ ├── README.md │ └── WeightedPathLength.cpp └── t ├── common.h └── gtest ├── gtest-all.cc ├── gtest.h └── gtest_main.cc /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.doc 3 | *.pdf 4 | todo 5 | prob 6 | t/gtest_main 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: cpp 2 | 3 | compiler: 4 | - gcc 5 | - clang 6 | 7 | env: 8 | - GLIBCXX_DEBUG=1 9 | - NO_GLIBCXX_DEBUG=1 10 | 11 | before_install: 12 | - sudo add-apt-repository --yes ppa:boost-latest/ppa 13 | - if [ "$CXX" == "g++" ]; then sudo add-apt-repository --yes ppa:ubuntu-toolchain-r/test; fi 14 | - if [ "$CXX" == "clang++" ]; then sudo add-apt-repository --yes ppa:h-rayflood/llvm; fi 15 | - sudo apt-get update -qq 16 | - sudo apt-get install -qq libboost1.54-all-dev 17 | - if [ "$CXX" = "g++" ]; then sudo apt-get install -qq g++-4.8; fi 18 | - if [ "$CXX" = "g++" ]; then export CXX="g++-4.8"; fi 19 | - if [ "$CXX" == "clang++" ]; then sudo apt-get install --allow-unauthenticated -qq clang-3.4; fi 20 | - if [ "$CXX" == "clang++" ]; then export CXX="clang++-3.4"; fi 21 | 22 | script: 23 | - rake test 24 | -------------------------------------------------------------------------------- /DataStructure/BinaryIndexedTree/BIT.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | template 6 | struct BIT { 7 | vector a; 8 | 9 | void init(int n) { 10 | vector(n + 1).swap(a); 11 | } 12 | 13 | void add(int i, T v) { 14 | for (int j = i + 1; j < (int)a.size(); j = (j | (j - 1)) + 1) { 15 | a[j] += v; 16 | } 17 | } 18 | 19 | // [0, i) 20 | T sum(int i) const { 21 | T ret = T(); 22 | for (int j = i; j > 0; j = j & (j - 1)) { 23 | ret += a[j]; 24 | } 25 | return ret; 26 | } 27 | 28 | T get(int i) const { 29 | return sum(i + 1) - sum(i); 30 | } 31 | 32 | void set(int i, T v) { 33 | add(i, v - get(i)); 34 | } 35 | }; 36 | 37 | -------------------------------------------------------------------------------- /DataStructure/BinaryIndexedTree/BIT.rs: -------------------------------------------------------------------------------- 1 | pub struct BIT(Vec); 2 | 3 | impl> BIT { 4 | pub fn new(n: usize) -> Self { 5 | Self(vec![Default::default(); n + 1]) 6 | } 7 | 8 | pub fn add(&mut self, mut i: usize, v: T) { 9 | i += 1; 10 | while i < self.0.len() { 11 | self.0[i] += v; 12 | i = (i | (i - 1)) + 1; 13 | } 14 | } 15 | 16 | pub fn partial_sum(&self, mut i: usize) -> T { 17 | let mut s = Default::default(); 18 | while i > 0 { 19 | s += self.0[i]; 20 | i = i & (i - 1); 21 | } 22 | s 23 | } 24 | 25 | pub fn sum(&self, range: impl ops::RangeBounds) -> T { 26 | use ops::Bound::*; 27 | let start = match range.start_bound() { 28 | Included(&i) => i, 29 | Excluded(&i) => i + 1, 30 | Unbounded => 0, 31 | }; 32 | let end = match range.end_bound() { 33 | Included(&i) => i + 1, 34 | Excluded(&i) => i, 35 | Unbounded => self.0.len() - 1, 36 | }; 37 | if start < end { 38 | self.partial_sum(end) - self.partial_sum(start) 39 | } else { 40 | Default::default() 41 | } 42 | } 43 | 44 | pub fn get(&self, i: usize) -> T { 45 | self.sum(i..=i) 46 | } 47 | 48 | pub fn set(&mut self, i: usize, v: T) { 49 | self.add(i, v - self.get(i)) 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /DataStructure/BinaryIndexedTree/README.md: -------------------------------------------------------------------------------- 1 | ## BIT.cpp 2 | 3 | #### Wiki 4 | 5 | * [Fenwick tree](http://en.wikipedia.org/wiki/Fenwick_tree) 6 | * [Binary Indexed Trees](http://community.topcoder.com/tc?module=Static&d1=tutorials&d2=binaryIndexedTrees) 7 | 8 | #### Prob 9 | 10 | 1. [CF163E](http://codeforces.com/problemset/problem/163/E) 11 | 2. [CF1625E2](https://codeforces.com/problemset/problem/1625/E2): 12 | [rs](...) 13 | 14 | ## BIT2D.cpp 15 | 16 | -------------------------------------------------------------------------------- /DataStructure/BinaryIndexedTree/t/BITGTest.cc: -------------------------------------------------------------------------------- 1 | #include "../BIT.cpp" 2 | #include "common.h" 3 | 4 | #include 5 | 6 | using namespace std; 7 | 8 | template 9 | static void test(const int n, const int m, const T a, const T b) { 10 | static const double EPS = 1e-8; 11 | BIT bit; 12 | vector vec(n); 13 | mt19937_64 rng; 14 | uniform_int_distribution idx(0, n - 1); 15 | RND val(a, b); 16 | 17 | bit.init(n); 18 | for (int k = 0; k < m; ++k) { 19 | int i = idx(rng); 20 | T v = val(rng); 21 | if (k % 2 == 0) { 22 | vec[i] = v; 23 | bit.set(i, v); 24 | } else { 25 | vec[i] += v; 26 | bit.add(i, v); 27 | } 28 | 29 | T sum = 0; 30 | for (int j = 0; j <= n; ++j) { 31 | ASSERT_NEAR((double)sum, (double)bit.sum(j), EPS); 32 | if (j < n) { 33 | ASSERT_NEAR((double)vec[j], (double)bit.get(j), EPS); 34 | sum += vec[j]; 35 | } 36 | } 37 | } 38 | } 39 | 40 | TEST(BITTest, Int) { 41 | const int N = 1000; 42 | const int M = 5000; 43 | const long long INF = 1LL << 50; 44 | test >(N, M, -INF, INF); 45 | } 46 | 47 | TEST(BITTest, Real) { 48 | const int N = 1024; 49 | const int M = 4096; 50 | const double INF = 10000; 51 | test >(N, M, -INF, INF); 52 | } 53 | 54 | -------------------------------------------------------------------------------- /DataStructure/DisjointSet/DisjointSet.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | struct DisjointSet { 6 | vector p; 7 | 8 | void init(int n) { 9 | p.resize(n); 10 | for (int i = 0; i < n; ++i) { 11 | p[i] = i; 12 | } 13 | } 14 | 15 | int getp(int i) { 16 | return i == p[i] ? i : (p[i] = getp(p[i])); 17 | } 18 | 19 | bool setp(int i, int j) { 20 | i = getp(i); 21 | j = getp(j); 22 | p[i] = j; 23 | return i != j; 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /DataStructure/DisjointSet/DisjointSet.rs: -------------------------------------------------------------------------------- 1 | pub struct DisjointSet(Vec); 2 | 3 | impl DisjointSet { 4 | pub fn new(n: usize) -> Self { 5 | DisjointSet((0..n).collect()) 6 | } 7 | 8 | pub fn clear(&mut self) { 9 | self.0.iter_mut().enumerate().for_each(|(i, j)| *j = i); 10 | } 11 | 12 | pub fn getp(&mut self, x: usize) -> usize { 13 | if self.0[x] != x { 14 | self.0[x] = self.getp(self.0[x]); 15 | } 16 | self.0[x] 17 | } 18 | 19 | pub fn setp(&mut self, x: usize, y: usize) -> Option<(usize, usize)> { 20 | let x = self.getp(x); 21 | let y = self.getp(y); 22 | self.0[x] = y; 23 | if x != y { 24 | Some((x, y)) 25 | } else { 26 | None 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /DataStructure/DisjointSet/ExtDisjointSet.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | struct ExtDisjointSet { 6 | vector p, s, t; 7 | 8 | static inline int RE(int i) { return ~i; } // !! 9 | 10 | void init(int n) { 11 | p.resize(n); 12 | s.resize(n); 13 | t.resize(n); 14 | for (int i = 0; i < n; ++i) { 15 | p[i] = i; 16 | s[i] = 1; 17 | t[i] = 0; 18 | } 19 | } 20 | 21 | int getp(int i) { 22 | if (i < 0) { 23 | return RE(getp(RE(i))); 24 | } else if (i == p[i]) { 25 | return i; 26 | } else { 27 | return p[i] = getp(p[i]); 28 | } 29 | } 30 | 31 | int setp(int i, int j) { 32 | i = getp(i); 33 | j = getp(j); 34 | if (i == j) { 35 | return 0; 36 | } else if (i == RE(j)) { 37 | return -1; 38 | } else { 39 | if (i < 0) { 40 | i = RE(i); 41 | j = RE(j); 42 | } 43 | p[i] = j; 44 | if (j >= 0) { 45 | s[j] += s[i]; 46 | t[j] += t[i]; 47 | } else { 48 | s[RE(j)] += t[i]; 49 | t[RE(j)] += s[i]; 50 | } 51 | return 1; 52 | } 53 | } 54 | } eds; 55 | 56 | -------------------------------------------------------------------------------- /DataStructure/DisjointSet/ExtDisjointSet.rs: -------------------------------------------------------------------------------- 1 | 2 | pub struct ExtDisjointSet(Vec); 3 | 4 | impl ExtDisjointSet { 5 | pub fn new(n: i32) -> Self { 6 | Self((0..n).collect()) 7 | } 8 | 9 | pub fn getp(&mut self, x: i32) -> i32 { 10 | if x < 0 { 11 | !self.getp(!x) 12 | } else { 13 | let i = x as usize; 14 | if self.0[i] == x { 15 | x 16 | } else { 17 | self.0[i] = self.getp(self.0[i]); 18 | self.0[i] 19 | } 20 | } 21 | } 22 | 23 | pub fn setp(&mut self, x: i32, y: i32) -> Result<(i32, i32), bool> { 24 | let x = self.getp(x); 25 | let y = self.getp(y); 26 | if x == y { 27 | Err(true) 28 | } else if x == !y { 29 | Err(false) 30 | } else { 31 | let (x, y) = if x >= 0 { (x, y) } else { (!x, !y) }; 32 | self.0[x as usize] = y; 33 | Ok((x, y)) 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /DataStructure/DisjointSet/README.md: -------------------------------------------------------------------------------- 1 | ## DisjointSet 2 | 3 | * Complexity: O(n) 4 | 5 | #### Prob 6 | 7 | 1. [CF1619G](https://codeforces.com/problemset/problem/1619/G) 8 | [rs](https://github.com/watashi/AlgoSolution/blob/master/codeforces/ac/16/1619/G.rs) 9 | 10 | ## ExtDisjointSet 11 | 12 | * Friend-enemy model 13 | * With size maintained 14 | * Complexity: O(n) 15 | 16 | #### Wiki 17 | 18 | #### Prob 19 | 20 | 1. [CF228E](http://codeforces.com/problemset/problem/228/E) 21 | 2. [CF1615C](https://codeforces.com/problemset/problem/1615/C) 22 | [rs](https://github.com/watashi/AlgoSolution/blob/master/codeforces/ac/16/1615/C.rs) 23 | -------------------------------------------------------------------------------- /DataStructure/DisjointSet/t/DisjointSetGTest.cc: -------------------------------------------------------------------------------- 1 | #include "../DisjointSet.cpp" 2 | #define DISJOINT_SET DisjointSet 3 | #include "GTestHelper.cpp" 4 | -------------------------------------------------------------------------------- /DataStructure/DisjointSet/t/ExtDisjointSetGTest.cc: -------------------------------------------------------------------------------- 1 | #include "../ExtDisjointSet.cpp" 2 | #define DISJOINT_SET ExtDisjointSet 3 | #include "GTestHelper.cpp" 4 | 5 | TEST_F(ExtDisjointSetTest, FriendEnemyExample) { 6 | const int n = 11; 7 | ExtDisjointSet ds; 8 | auto r = ExtDisjointSet::RE; 9 | auto setp = [&ds](int i, int j){ 10 | if (rand(2) == 0) { 11 | swap(i, j); 12 | } 13 | return ds.setp(i, j); 14 | }; 15 | 16 | srand(0); 17 | ds.init(n); 18 | for (int i = 0; i < n; ++i) { 19 | // self 20 | ASSERT_EQ(-1, setp(i, r(i))); 21 | ASSERT_TRUE(ds.getp(i) == r(ds.getp(r(i)))); 22 | if ((i ^ 1) < n) { 23 | // enemy 24 | ASSERT_EQ(1 - i % 2, setp(i, r(i ^ 1))); 25 | ASSERT_TRUE(ds.getp(i) == r(ds.getp(i ^ 1))); 26 | } 27 | } 28 | for (int i = 0; i < n; ++i) { 29 | for (int j = 0; j < i; ++j) { 30 | if (i % 2 == j % 2) { 31 | // friend 32 | ASSERT_NE(-1, ds.setp(i, j)); 33 | } 34 | } 35 | } 36 | // test 37 | for (int i = 0; i < n; ++i) { 38 | for (int j = 0; j < n; ++j) { 39 | if (i % 2 == j % 2) { 40 | ASSERT_TRUE(ds.getp(i) == ds.getp(j)); 41 | } else { 42 | ASSERT_TRUE(ds.getp(i) == r(ds.getp(j))); 43 | } 44 | } 45 | } 46 | // size 47 | int root = ds.getp(0); 48 | root = root < 0 ? r(root) : root; 49 | ASSERT_EQ(root % 2 == 0 ? 6 : 5, ds.s[root]); 50 | ASSERT_EQ(root % 2 == 0 ? 5 : 6, ds.t[root]); 51 | } 52 | 53 | -------------------------------------------------------------------------------- /DataStructure/DisjointSet/t/GTestHelper.cpp: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | 3 | // #include 4 | #include 5 | 6 | using namespace boost; 7 | 8 | #define DISJOINT_SET_TEST CONCAT_EX(DISJOINT_SET, Test) 9 | 10 | class DISJOINT_SET_TEST: public ::testing::TestWithParam { 11 | public: 12 | static const int MAXN = 1 << 20; 13 | 14 | protected: 15 | struct Query { 16 | int op, a, b; 17 | }; 18 | 19 | void test(int n, const vector& q) { 20 | disjoint_sets_with_storage<> ds2(n); 21 | 22 | ds.init(n); 23 | for (auto i: q) { 24 | switch (i.op) { 25 | case 0: 26 | ASSERT_EQ(ds.getp(i.a) == ds.getp(i.b), 27 | ds2.find_set(i.a) == ds2.find_set(i.b)); 28 | break; 29 | case 1: 30 | ASSERT_EQ(ds.setp(i.a, i.b), 31 | ds2.find_set(i.a) != ds2.find_set(i.b)); 32 | ds2.union_set(i.a, i.b); 33 | break; 34 | } 35 | } 36 | } 37 | 38 | static DISJOINT_SET ds; 39 | }; 40 | 41 | DISJOINT_SET DISJOINT_SET_TEST::ds; 42 | 43 | TEST_F_EX(DISJOINT_SET_TEST, FriendOnlyExample) { 44 | int n = 5; 45 | vector q = { 46 | {1, 1, 1}, {0, 1, 2}, 47 | // (1, 2) 48 | {1, 1, 2}, {0, 1, 2}, {0, 1, 0}, 49 | // (1, 2, 3) 50 | {1, 2, 3}, {0, 2, 3}, {0, 1, 3}, {0, 0, 3}, 51 | // (1, 2, 3), (0, 4) 52 | {1, 0, 4}, {0, 0, 1}, {0, 3, 4}, {0, 1, 4}, 53 | // (0, 1, 2, 3, 4) 54 | {1, 2, 4}, {0, 0, 1}, {0, 3, 4}, {0, 1, 4}, 55 | }; 56 | test(n, q); 57 | } 58 | 59 | TEST_P_EX(DISJOINT_SET_TEST, FriendOnlyRandom) { 60 | int n = GetParam(); 61 | srand(n); 62 | int m = n * rand(2, 5); 63 | vector q; 64 | for (int i = 0; i < m; ++i) { 65 | int a = rand(n); 66 | int b = rand(n); 67 | if (rand(3) == 0) { 68 | q.push_back({1, a, b}); 69 | q.push_back({0, a, rand(n)}); 70 | q.push_back({0, b, rand(n)}); 71 | } else { 72 | q.push_back({0, a, b}); 73 | } 74 | } 75 | test(n, q); 76 | } 77 | 78 | INSTANTIATE_TEST_CASE_P_EX(, DISJOINT_SET_TEST, 79 | ::testing::Values(10, 100, 1000, 10000, 100000, DISJOINT_SET_TEST::MAXN)); 80 | -------------------------------------------------------------------------------- /DataStructure/RangeMinimumQuery/README.md: -------------------------------------------------------------------------------- 1 | ## RMQ.cpp 2 | 3 | #### Prob 4 | 5 | 1. [AOJ2444](http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2444) 6 | 2. [CF1620F](https://codeforces.com/problemset/problem/1609/E): 7 | [rs](https://github.com/watashi/AlgoSolution/blob/master/codeforces/ac/16/1620/F.greedy.rs) 8 | 9 | ## RMQ2D.cpp 10 | 11 | -------------------------------------------------------------------------------- /DataStructure/RangeMinimumQuery/RMQ.cpp: -------------------------------------------------------------------------------- 1 | #include // copy 2 | #include // CHAR_BIT 3 | #include 4 | 5 | using namespace std; 6 | 7 | template 8 | struct RMQ { 9 | int n; 10 | vector e; 11 | vector > rmq; 12 | 13 | static const int INT_BIT = sizeof(4) * CHAR_BIT; 14 | static inline int LG2(int i) { return INT_BIT - 1 - __builtin_clz(i); } 15 | static inline int BIN(int i) { return 1 << i; } 16 | 17 | int cmp(int l, int r) const { 18 | return e[l] <= e[r] ? l : r; 19 | } 20 | 21 | void init(int n, const T e[]) { 22 | this->n = n; 23 | vector(e, e + n).swap(this->e); 24 | 25 | int m = 1; 26 | while (BIN(m) <= n) { 27 | ++m; 28 | } 29 | vector >(m, vector(n)).swap(rmq); 30 | 31 | for (int i = 0; i < n; ++i) { 32 | rmq[0][i] = i; 33 | } 34 | for (int i = 0; BIN(i + 1) <= n; ++i) { 35 | for (int j = 0; j + BIN(i + 1) <= n; ++j) { 36 | rmq[i + 1][j] = cmp(rmq[i][j], rmq[i][j + BIN(i)]); 37 | } 38 | } 39 | } 40 | 41 | int index(int l, int r) const { 42 | int b = LG2(r - l); 43 | return cmp(rmq[b][l], rmq[b][r - (1 << b)]); 44 | } 45 | 46 | T value(int l, int r) const { 47 | return e[index(l, r)]; 48 | } 49 | }; 50 | 51 | -------------------------------------------------------------------------------- /DataStructure/RangeMinimumQuery/RMQ.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE FlexibleContexts #-} 2 | {-# LANGUAGE RecordWildCards #-} 3 | 4 | import Data.Array.IArray 5 | import Data.Array.Unboxed 6 | import Data.Bits 7 | 8 | -- ----------------------------------------------------------------------------- 9 | -- RMQ 10 | 11 | data RMQ a = RMQ 12 | { rmqCmp :: a -> a -> Bool 13 | , rmqIdx :: Array Int (UArray Int Int) 14 | , rmqVal :: Array Int a 15 | } 16 | 17 | logBase2 :: Int -> Int 18 | logBase2 n = finiteBitSize n - 1 - countLeadingZeros n 19 | 20 | rmqFromList :: (a -> a -> Bool) -> [a] -> RMQ a 21 | rmqFromList rmqCmp a = RMQ{..} 22 | where 23 | n = length a 24 | cmp i j = if rmqCmp (rmqVal!i) (rmqVal!j) then i else j 25 | rmqVal = listArray (0, n-1) a 26 | rmqIdx = listArray (0, logBase2 n) $ go 1 $ indices rmqVal 27 | where 28 | go d idx 29 | | d > n = [] 30 | | otherwise = listArray (0, n-d) idx: go (d + d) idx' 31 | where 32 | idx' = zipWith cmp idx $ drop d idx 33 | 34 | rmqQuery :: RMQ a -> (Int, Int) -> (Int, a) 35 | rmqQuery RMQ{..} (lo, hi) = if rmqCmp ai aj then (i, ai) else (j, aj) 36 | where 37 | k = logBase2 $ hi - lo 38 | i = rmqIdx!k!lo 39 | j = let mi = hi - 1 `unsafeShiftL` k in rmqIdx!k!mi 40 | ai = rmqVal!i 41 | aj = rmqVal!j 42 | 43 | {- 44 | {-# LANGUAGE MagicHash #-} 45 | {-# LANGUAGE UnboxedTuples #-} 46 | import GHC.Prim 47 | import GHC.Types 48 | 49 | logBase2 (I# x) = I# ret 50 | where 51 | (# _, ret #) = go 1# (go 2# (go 4# (go 8# (go 16# (# x, 0# #))))) 52 | 53 | go :: Int# -> (# Int#, Int# #) -> (# Int#, Int# #) 54 | go k (# n, m #) = case uncheckedIShiftRA# n k of 55 | 0# -> (# n, m #) 56 | n' -> (# n', m +# k #) 57 | -} 58 | -------------------------------------------------------------------------------- /DataStructure/RangeMinimumQuery/RMQ.rs: -------------------------------------------------------------------------------- 1 | pub struct RMQ { 2 | index: Vec>, 3 | value: Vec, 4 | } 5 | 6 | impl RMQ { 7 | fn min(v: &Vec, i: usize, j: usize) -> usize { 8 | if v[i].cmp(&v[j]).is_le() { 9 | i 10 | } else { 11 | j 12 | } 13 | } 14 | 15 | pub fn new(value: Vec) -> Self { 16 | let mut index = vec![]; 17 | let mut prev = (0..value.len()).collect::>(); 18 | let mut step = 1; 19 | while !prev.is_empty() { 20 | let next = prev 21 | .iter() 22 | .zip(prev.iter().skip(step)) 23 | .map(|(&i, &j)| Self::min(&value, i, j)) 24 | .collect(); 25 | index.push(prev); 26 | prev = next; 27 | step *= 2; 28 | } 29 | RMQ { 30 | index: index, 31 | value: value, 32 | } 33 | } 34 | 35 | pub fn index(&self, start: usize, end: usize) -> usize { 36 | let n = (usize::BITS - (end - start).leading_zeros() - 1) as usize; 37 | Self::min( 38 | &self.value, 39 | self.index[n][start], 40 | self.index[n][end - (1 << n)], 41 | ) 42 | } 43 | 44 | pub fn value(&self, start: usize, end: usize) -> &T { 45 | &self.value[self.index(start, end)] 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /DataStructure/RangeMinimumQuery/t/RMQGTest.cc: -------------------------------------------------------------------------------- 1 | #include "../RMQ.cpp" 2 | #include "common.h" 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | 10 | TEST(RMQTest, Value) { 11 | const int N = 512; 12 | mt19937 rng; 13 | uniform_real_distribution urd; 14 | RMQ rmq; 15 | vector v(N); 16 | 17 | generate(v.begin(), v.end(), [&]{ return urd(rng); }); 18 | rmq.init((int)v.size(), &v[0]); 19 | for (int i = 0; i < N; ++i) { 20 | double val = v[i]; 21 | for (int j = i; j < N; ++j) { 22 | val = min(val, v[j]); 23 | ASSERT_EQ(val, rmq.value(i, j + 1)); 24 | } 25 | } 26 | } 27 | 28 | TEST(RMQTest, Index) { 29 | const int N = 513; 30 | mt19937 rng; 31 | uniform_int_distribution uid('0', '9'); 32 | RMQ rmq; 33 | string s(N, '\0'); 34 | 35 | generate(s.begin(), s.end(), [&]{ return uid(rng); }); 36 | rmq.init((int)s.size(), &s[0]); 37 | for (int i = 0; i < N; ++i) { 38 | int idx = i; 39 | for (int j = i; j < N; ++j) { 40 | if (s[j] < s[idx]) { 41 | idx = j; 42 | } 43 | ASSERT_EQ(idx, rmq.index(i, j + 1)); 44 | } 45 | } 46 | } 47 | 48 | -------------------------------------------------------------------------------- /DataStructure/SegmentTree/README.md: -------------------------------------------------------------------------------- 1 | #### Wiki 2 | 3 | * [Segment tree](https://en.wikipedia.org/wiki/Segment_tree) 4 | 5 | #### Prob 6 | 7 | 1. [CF1609E](https://codeforces.com/problemset/problem/1609/E): 8 | [rs](https://github.com/watashi/AlgoSolution/blob/master/codeforces/ac/16/1609/E.rs) 9 | 2. [CF1609G](https://codeforces.com/problemset/problem/1609/G): 10 | [rs](https://github.com/watashi/AlgoSolution/blob/master/codeforces/ac/16/1609/G.rs) 11 | 3. [CF1614E](https://codeforces.com/problemset/problem/1614/E): 12 | [rs](https://github.com/watashi/AlgoSolution/blob/master/codeforces/ac/16/1614/E.GenericSegTree.rs) 13 | -------------------------------------------------------------------------------- /DataStructure/SegmentTree/SegmentTree.rs: -------------------------------------------------------------------------------- 1 | type SegTreeIndex = i32; 2 | 3 | pub trait SegTreeMonoid: Copy { 4 | fn empty(start: SegTreeIndex, end: SegTreeIndex) -> Self; 5 | fn append(&self, other: &Self) -> Self; 6 | } 7 | 8 | pub trait SegTreeOp: Copy { 9 | fn apply(&self, start: SegTreeIndex, end: SegTreeIndex, value: &mut T); 10 | fn combine(&mut self, other: &Self); 11 | } 12 | 13 | impl SegTreeOp for T { 14 | fn apply(&self, _: SegTreeIndex, _: SegTreeIndex, value: &mut T) { 15 | *value = value.append(self); 16 | } 17 | 18 | fn combine(&mut self, other: &Self) { 19 | *self = self.append(other); 20 | } 21 | } 22 | 23 | pub struct SegTree { 24 | start: SegTreeIndex, 25 | end: SegTreeIndex, 26 | value: T, 27 | op: Option, 28 | left: Option>, 29 | right: Option>, 30 | } 31 | 32 | impl> SegTree { 33 | pub fn new(start: SegTreeIndex, end: SegTreeIndex) -> Self { 34 | SegTree { 35 | start: start, 36 | end: end, 37 | value: T::empty(start, end), 38 | op: None, 39 | left: None, 40 | right: None, 41 | } 42 | } 43 | 44 | pub fn is_leaf(&self) -> bool { 45 | self.end - self.start == 1 46 | } 47 | 48 | fn lazy_apply(&mut self, op: Op) { 49 | op.apply(self.start, self.end, &mut self.value); 50 | if !self.is_leaf() { 51 | match self.op.as_mut() { 52 | Some(x) => { 53 | x.combine(&op); 54 | } 55 | None => self.op = Some(op), 56 | } 57 | } 58 | } 59 | 60 | fn force(&mut self) -> (&mut Self, &mut Self) { 61 | debug_assert!(!self.is_leaf()); 62 | if self.left.is_none() 63 | /* && self.right.is_none() */ 64 | { 65 | let mid = (self.start + self.end) / 2; 66 | self.left = Some(Box::new(Self::new(self.start, mid))); 67 | self.right = Some(Box::new(Self::new(mid, self.end))); 68 | } 69 | let left = self.left.as_deref_mut().unwrap(); 70 | let right = self.right.as_deref_mut().unwrap(); 71 | if let Some(op) = self.op { 72 | left.lazy_apply(op); 73 | right.lazy_apply(op); 74 | self.op = None; 75 | } 76 | (left, right) 77 | } 78 | 79 | pub fn apply(&mut self, start: SegTreeIndex, end: SegTreeIndex, op: Op) { 80 | debug_assert!(start < self.end && self.start < end && start < end); 81 | if start <= self.start && self.end <= end { 82 | self.lazy_apply(op); 83 | } else { 84 | let (left, right) = self.force(); 85 | if start < left.end { 86 | left.apply(start, end, op); 87 | } 88 | if right.start < end { 89 | right.apply(start, end, op); 90 | } 91 | self.value = left.value.append(&right.value); 92 | } 93 | } 94 | 95 | pub fn query(&mut self, start: SegTreeIndex, end: SegTreeIndex) -> T { 96 | debug_assert!(start < self.end && self.start < end && start < end); 97 | if start <= self.start && self.end <= end { 98 | self.value 99 | } else { 100 | let (left, right) = self.force(); 101 | if end <= left.end { 102 | left.query(start, end) 103 | } else if right.start <= start { 104 | right.query(start, end) 105 | } else { 106 | left.query(start, end).append(&right.query(start, end)) 107 | } 108 | } 109 | } 110 | 111 | pub fn bsearch(&mut self, start: SegTreeIndex, end: SegTreeIndex, f: &F) -> SegTreeIndex 112 | where 113 | F: Fn(&T) -> bool, 114 | { 115 | debug_assert!(start < self.end && self.start < end && start < end); 116 | if !f(&self.value) { 117 | end 118 | } else if self.is_leaf() { 119 | self.start 120 | } else { 121 | let (left, right) = self.force(); 122 | if end <= left.end { 123 | left.bsearch(start, end, f) 124 | } else if right.start <= start { 125 | right.bsearch(start, end, f) 126 | } else { 127 | let ret = left.bsearch(start, end, f); 128 | if ret != end { 129 | ret 130 | } else { 131 | right.bsearch(start, end, f) 132 | } 133 | } 134 | } 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /Graph/Connectivity/BiconnectedComponents/BridgeBlockTree.cpp: -------------------------------------------------------------------------------- 1 | template 2 | struct BridgeBlockTree { 3 | Tarjan bcc; 4 | DisjointSet ds; 5 | vector e[MAXN]; 6 | 7 | void init(int n) { 8 | bcc.init(n); 9 | ds.init(n); 10 | } 11 | 12 | void add(int a, int b) { 13 | bcc.add(a, b); 14 | } 15 | 16 | void gao() { 17 | bcc.gao(); 18 | for (const auto& i: bcc.bcc) { 19 | if (i.size() > 1) { 20 | for (const auto& j: i) { 21 | ds.setp(j.first, j.second); 22 | } 23 | } 24 | } 25 | for (const auto& i: bcc.bridge) { 26 | int a = ds.getp(i.first); 27 | int b = ds.getp(i.second); 28 | e[a].push_back(b); 29 | e[b].push_back(a); 30 | } 31 | } 32 | 33 | int id(int v) { 34 | return ds.getp(v); 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /Graph/Connectivity/BiconnectedComponents/README.md: -------------------------------------------------------------------------------- 1 | ## Tarjan.cpp 2 | 3 | #### Wiki 4 | 5 | * [Biconnected component](http://en.wikipedia.org/wiki/Biconnected_component) 6 | 7 | > In graph theory, a **biconnected component** (or **2-connected component**) is a maximal biconnected subgraph. Any connected graph decomposes into a tree of biconnected components called the **block tree** of the graph. The blocks are attached to each other at shared vertices called **cut vertices** or **articulation points**. Specifically, a **cut vertex** is any vertex whose removal increases the number of connected components. 8 | 9 | ## BridgeBlockTree.cpp 10 | 11 | #### Wiki 12 | 13 | * [Bridge (graph theory)](http://en.wikipedia.org/wiki/Bridge_%28graph_theory%29) 14 | 15 | > In graph theory, a **bridge** (also known as a **cut-edge** or **cut arc** or an **isthmus**) is an edge whose deletion increases the number of connected components. Equivalently, an edge is a bridge if and only if it is not contained in any cycle. A graph is said to be **bridgeless** if it contains no bridges. 16 | 17 | > The **bridge-block tree** of the graph has a vertex for every nontrivial **2-edge-connected** and an edge for every bridge. 18 | 19 | * [Bridgeless graphs](http://en.wikipedia.org/wiki/Bridge_%28graph_theory%29#Bridgeless_graphs) 20 | 21 | * [How to increase the size of min-cut in graph by adding minimum number of edges](http://stackoverflow.com/questions/12757476/how-to-increase-the-size-of-min-cut-in-graph-by-adding-minimum-number-of-edges) 22 | 23 | #### Prob 24 | 25 | 1. [CF45H](http://codeforces.com/problemset/problem/45/H) _Add minimum edges to ensure the graph is bridgeless_ 26 | -------------------------------------------------------------------------------- /Graph/Connectivity/BiconnectedComponents/Tarjan.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | // TODO: cannot handle duplicate edges 9 | struct Tarjan { 10 | int n; 11 | vector > e; 12 | 13 | vector cut; 14 | vector > bridge; 15 | vector > > bcc; 16 | 17 | void init(int n) { 18 | this->n = n; 19 | e.clear(); 20 | e.resize(n); 21 | dfn.resize(n); 22 | low.resize(n); 23 | } 24 | 25 | void add(int a, int b) { 26 | // assert(find(e[a].begin(), e[a].end(), b) == e[a].end()); 27 | e[a].push_back(b); 28 | e[b].push_back(a); 29 | } 30 | 31 | vector dfn, low; 32 | int timestamp; 33 | stack > s; 34 | 35 | void dfs(int v, int p) { 36 | int part = p == -1 ? 0 : 1; 37 | dfn[v] = low[v] = timestamp++; 38 | for (vector::const_iterator w = e[v].begin(); w != e[v].end(); ++w) { 39 | pair f = make_pair(min(v, *w), max(v, *w)); 40 | if (dfn[*w] == -1) { 41 | s.push(f); 42 | dfs(*w, v); 43 | low[v] = min(low[v], low[*w]); 44 | if (dfn[v] <= low[*w]) { 45 | // articulation point 46 | if (++part == 2) { 47 | cut.push_back(v); 48 | } 49 | // articulation edge 50 | if (dfn[v] < low[*w]) { 51 | bridge.push_back(f); 52 | } 53 | // biconnected component (2-vertex-connected) 54 | vector > t; 55 | do { 56 | t.push_back(s.top()); 57 | s.pop(); 58 | } while (t.back() != f); 59 | bcc.push_back(t); 60 | } 61 | } else if (*w != p && dfn[*w] < dfn[v]) { 62 | s.push(f); 63 | low[v] = min(low[v], dfn[*w]); 64 | } 65 | } 66 | } 67 | 68 | void gao() { 69 | cut.clear(); 70 | bridge.clear(); 71 | bcc.clear(); 72 | 73 | timestamp = 0; 74 | stack >().swap(s); 75 | fill(dfn.begin(), dfn.end(), -1); 76 | 77 | for (int i = 0; i < n; ++i) { 78 | if (dfn[i] == -1) { 79 | dfs(i, -1); 80 | } 81 | } 82 | } 83 | }; 84 | 85 | -------------------------------------------------------------------------------- /Graph/Connectivity/BiconnectedComponents/t/TarjanGTest.cc: -------------------------------------------------------------------------------- 1 | #include "../Tarjan.cpp" 2 | #include "common.h" 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace boost; 9 | 10 | typedef adjacency_list > graph_t; 12 | 13 | class BCCTarjanTest: public ::testing::TestWithParam > { 14 | protected: 15 | static const int MAXN = 100100; 16 | static Tarjan tarjan; 17 | }; 18 | 19 | Tarjan BCCTarjanTest::tarjan; 20 | 21 | TEST_P(BCCTarjanTest, Random) { 22 | int n, m; 23 | graph_t g; 24 | set > st; 25 | vector > e; 26 | 27 | tie(n, m) = GetParam(); 28 | srand(n ^ m); 29 | tarjan.init(n); 30 | for (int i = 0; i < m; ++i) { 31 | int a = rand() % n; 32 | int b = rand() % n; 33 | if (a > b) { 34 | swap(a, b); 35 | } 36 | if (a != b && st.insert({a, b}).second) { 37 | e.push_back({a, b}); 38 | if (rand() % 2 == 0) { 39 | swap(a, b); 40 | } 41 | tarjan.add(a, b); 42 | add_edge(a, b, (int)e.size() - 1, g); 43 | } 44 | } 45 | m = (int)e.size(); 46 | tarjan.gao(); 47 | 48 | vector cut; 49 | articulation_points(g, back_inserter(cut)); 50 | ASSERT_EQ(normalize(cut), normalize(tarjan.cut)) << "articulation points"; 51 | 52 | vector comp(m); 53 | size_t ncomp = biconnected_components(g, 54 | make_iterator_property_map(comp.begin(), get(edge_index, g))); 55 | ASSERT_EQ(ncomp, tarjan.bcc.size()) << "number of biconnected components"; 56 | 57 | vector > > bcc(ncomp); 58 | for (int i = 0; i < m; ++i) { 59 | bcc[comp[i]].push_back(e[i]); 60 | } 61 | ASSERT_EQ(normalize(bcc), normalize(tarjan.bcc)) << "biconnected components"; 62 | } 63 | 64 | static vector > params = { 65 | {10, 20}, {10, 30}, {10, 50}, {10, 70}, {10, 100}, 66 | {20, 20}, {20, 30}, {20, 50}, {20, 70}, {20, 100}, 67 | {30, 20}, {30, 30}, {30, 50}, {30, 70}, {30, 100}, 68 | { 100, 500}, 69 | { 1000, 5000}, 70 | { 10000, 50000}, 71 | {100000, 500000}, 72 | }; 73 | 74 | INSTANTIATE_TEST_CASE_P(, BCCTarjanTest, ::testing::ValuesIn(params)); 75 | -------------------------------------------------------------------------------- /Graph/Connectivity/StrongComponents/Kosaraju.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | struct SCCKosaraju { 7 | int n; 8 | vector > e, re; 9 | 10 | vector id; 11 | vector > scc; 12 | 13 | void init(int n) { 14 | this->n = n; 15 | vector >(n).swap(e); 16 | vector >(n).swap(re); 17 | id.resize(n); 18 | } 19 | 20 | void add(int a, int b) { 21 | e[a].push_back(b); 22 | re[b].push_back(a); 23 | } 24 | 25 | vector todo; 26 | 27 | void dfs(int v) { 28 | id[v] = v; 29 | for (vector::const_iterator w = e[v].begin(); w != e[v].end(); ++w) { 30 | if (id[*w] == -1) { 31 | dfs(*w); 32 | } 33 | } 34 | todo.push_back(v); 35 | } 36 | 37 | void rdfs(int v) { 38 | id[v] = (int)scc.size() - 1; 39 | scc.back().push_back(v); 40 | for (vector::const_iterator w = re[v].begin(); w != re[v].end(); ++w) { 41 | if (id[*w] == -1) { 42 | rdfs(*w); 43 | } 44 | } 45 | } 46 | 47 | int gao() { 48 | todo.clear(); 49 | fill(id.begin(), id.end(), -1); 50 | for (int i = 0; i < n; ++i) { 51 | if (id[i] == -1) { 52 | dfs(i); 53 | } 54 | } 55 | 56 | scc.clear(); 57 | reverse(todo.begin(), todo.end()); 58 | fill(id.begin(), id.end(), -1); 59 | for (int i = 0; i < n; ++i) { 60 | if (id[todo[i]] == -1) { 61 | scc.push_back(vector()); 62 | rdfs(todo[i]); 63 | } 64 | } 65 | 66 | return (int)scc.size(); 67 | } 68 | }; 69 | 70 | -------------------------------------------------------------------------------- /Graph/Connectivity/StrongComponents/Tarjan.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | struct SCCTarjan { 8 | int n; 9 | vector > e; 10 | 11 | vector id; 12 | vector > scc; 13 | 14 | void init(int n) { 15 | this->n = n; 16 | vector >(n).swap(e); 17 | id.resize(n); 18 | dfn.resize(n); 19 | low.resize(n); 20 | } 21 | 22 | void add(int a, int b) { 23 | e[a].push_back(b); 24 | } 25 | 26 | vector dfn, low; 27 | int timestamp; 28 | stack s; 29 | 30 | void dfs(int v) { 31 | dfn[v] = timestamp++; 32 | low[v] = dfn[v]; 33 | s.push(v); 34 | for (vector::const_iterator w = e[v].begin(); w != e[v].end(); ++w) { 35 | if (dfn[*w] == -1) { 36 | dfs(*w); 37 | low[v] = min(low[v], low[*w]); 38 | } else if (dfn[*w] != -2) { 39 | low[v] = min(low[v], dfn[*w]); 40 | } 41 | } 42 | 43 | if (low[v] == dfn[v]) { 44 | vector t; 45 | do { 46 | int w = s.top(); 47 | s.pop(); 48 | id[w] = (int)scc.size(); 49 | t.push_back(w); 50 | dfn[w] = -2; 51 | } while (t.back() != v); 52 | scc.push_back(t); 53 | } 54 | } 55 | 56 | int gao() { 57 | scc.clear(); 58 | stack().swap(s); 59 | timestamp = 0; 60 | 61 | fill(dfn.begin(), dfn.end(), -1); 62 | for (int i = 0; i < n; ++i) { 63 | if (dfn[i] == -1) { 64 | dfs(i); 65 | } 66 | } 67 | return (int)scc.size(); 68 | } 69 | }; 70 | 71 | -------------------------------------------------------------------------------- /Graph/Connectivity/StrongComponents/t/GTestHelper.cpp: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | 3 | #include 4 | #include 5 | 6 | using namespace boost; 7 | 8 | #define SCCTest CONCAT_EX(SCC, Test) 9 | 10 | class SCCTest: public ::testing::TestWithParam > { 11 | protected: 12 | static const int MAXN = 100100; 13 | static SCC scc; 14 | }; 15 | 16 | SCC SCCTest::scc; 17 | 18 | TEST_P_EX(SCCTest, Random) { 19 | int n, m; 20 | adjacency_list g; 21 | 22 | tie(n, m) = GetParam(); 23 | srand(n ^ m); 24 | scc.init(n); 25 | for (int i = 0; i < m; ++i) { 26 | int a = rand() % n; 27 | int b = rand() % n; 28 | scc.add(a, b); 29 | add_edge(a, b, g); 30 | } 31 | for (int i = 0; i < n; ++i) { 32 | if (scc.e[i].empty()) { 33 | int a = i; 34 | int b = rand() % n; 35 | scc.add(a, b); 36 | add_edge(a, b, g); 37 | } 38 | } 39 | scc.gao(); 40 | 41 | vector_property_map id(n); 42 | size_t ncomp = strong_components(g, id); 43 | ASSERT_EQ(ncomp, scc.scc.size()) << "number of strong components"; 44 | 45 | vector > v(ncomp); 46 | for (int i = 0; i < n; ++i) { 47 | v[id[i]].push_back(i); 48 | } 49 | ASSERT_EQ(normalize(v), normalize(scc.scc)) << "strong components"; 50 | } 51 | 52 | static const vector > params = { 53 | {10, 20}, {10, 30}, {10, 50}, {10, 70}, {10, 110}, 54 | {20, 20}, {20, 30}, {20, 50}, {20, 70}, {20, 110}, 55 | {30, 20}, {30, 30}, {30, 50}, {30, 70}, {30, 110}, 56 | { 100, 1000}, 57 | { 1000, 10000}, 58 | { 10000, 100000}, 59 | {100000, 1000000} 60 | }; 61 | 62 | INSTANTIATE_TEST_CASE_P_EX(, SCCTest, ::testing::ValuesIn(params)); 63 | -------------------------------------------------------------------------------- /Graph/Connectivity/StrongComponents/t/KosarajuGTest.cc: -------------------------------------------------------------------------------- 1 | #include "../Kosaraju.cpp" 2 | #define SCC SCCKosaraju 3 | #include "GTestHelper.cpp" 4 | -------------------------------------------------------------------------------- /Graph/Connectivity/StrongComponents/t/TarjanGTest.cc: -------------------------------------------------------------------------------- 1 | #include "../Tarjan.cpp" 2 | #define SCC SCCTarjan 3 | #include "GTestHelper.cpp" 4 | -------------------------------------------------------------------------------- /Graph/FlowNetwork/MinCostMaxFlow/MinCostMaxFlow.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | template 10 | struct MinCostMaxFlow { 11 | struct NegativeCostCircuitExistsException { 12 | }; 13 | 14 | struct Edge { 15 | int v; 16 | T c; 17 | S w; 18 | int b; 19 | Edge(int v, T c, S w, int b) : v(v), c(c), w(w), b(b) { } 20 | }; 21 | 22 | int n, source, sink; 23 | vector e[MAXN]; 24 | 25 | void init(int n, int source, int sink) { 26 | this->n = n; 27 | this->source = source; 28 | this->sink = sink; 29 | for (int i = 0; i < n; ++i) { 30 | e[i].clear(); 31 | } 32 | } 33 | 34 | void addEdge(int a, int b, T c, S w) { 35 | e[a].push_back(Edge(b, c, w, e[b].size())); 36 | e[b].push_back(Edge(a, 0, -w, e[a].size() - 1)); // TODO 37 | } 38 | 39 | bool mark[MAXN]; 40 | T maxc[MAXN]; 41 | S minw[MAXN]; 42 | int dist[MAXN]; 43 | Edge* prev[MAXN]; 44 | 45 | bool _spfa() { 46 | queue q; 47 | fill(mark, mark + n, false); 48 | fill(maxc, maxc + n, 0); 49 | fill(minw, minw + n, numeric_limits::max()); 50 | fill(dist, dist + n, 0); 51 | fill(prev, prev + n, (Edge*)NULL); 52 | mark[source] = true; 53 | maxc[source] = numeric_limits::max(); 54 | minw[source] = 0; 55 | 56 | q.push(source); 57 | while (!q.empty()) { 58 | int cur = q.front(); 59 | mark[cur] = false; 60 | q.pop(); 61 | for (typename vector::iterator it = e[cur].begin(); it != e[cur].end(); ++it) { 62 | T c = min(maxc[cur], it->c); 63 | if (c == 0) { 64 | continue; 65 | } 66 | 67 | int v = it->v; 68 | S w = minw[cur] + it->w; 69 | if (minw[v] > w || (minw[v] == w && maxc[v] < c)) { // TODO 70 | maxc[v] = c; 71 | minw[v] = w; 72 | dist[v] = dist[cur] + 1; 73 | if (dist[v] >= n) { 74 | return false; 75 | } 76 | prev[v] = &*it; 77 | if (!mark[v]) { 78 | mark[v] = true; 79 | q.push(v); 80 | } 81 | } 82 | } 83 | } 84 | return true; 85 | } 86 | 87 | pair gao() { 88 | T sumc = 0; 89 | S sumw = 0; 90 | while (true) { 91 | if (!_spfa()) { 92 | throw NegativeCostCircuitExistsException(); 93 | } else if (maxc[sink] == 0) { 94 | break; 95 | } else { 96 | T c = maxc[sink]; 97 | sumc += c; 98 | sumw += c * minw[sink]; 99 | 100 | int cur = sink; 101 | while (cur != source) { 102 | Edge* e1 = prev[cur]; 103 | e1->c -= c; 104 | Edge* e2 = &e[e1->v][e1->b]; 105 | e2->c += c; 106 | cur = e2->v; 107 | } 108 | } 109 | } 110 | return make_pair(sumc, sumw); 111 | } 112 | }; 113 | 114 | -------------------------------------------------------------------------------- /Graph/FlowNetwork/MinCostMaxFlow/README.md: -------------------------------------------------------------------------------- 1 | ## MinCostMaxFlow.cpp 2 | 3 | #### Prob 4 | 5 | 1. [CF164C](http://codeforces.com/problemset/problem/164/C) #2472669(3484ms) 6 | 2. [CF237E](http://codeforces.com/problemset/problem/237/E) 7 | 8 | ## UnitMinCostMaxFlow.cpp 9 | 10 | #### Prob 11 | 12 | 1. [CF164C](http://codeforces.com/problemset/problem/164/C) #2472664(3140ms) 13 | 14 | -------------------------------------------------------------------------------- /Graph/FlowNetwork/MinCostMaxFlow/UnitMinCostMaxFlow.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace std; 8 | 9 | template 10 | struct MinCostMaxFlow { 11 | struct NegativeCostCircuitExistsException { 12 | }; 13 | 14 | struct Edge { 15 | int v; 16 | bool c; 17 | S w; 18 | int b; 19 | Edge(int v, bool c, S w, int b) : v(v), c(c), w(w), b(b) { } 20 | }; 21 | 22 | int n, source, sink; 23 | vector e[MAXN]; 24 | 25 | void init(int n, int source, int sink) { 26 | this->n = n; 27 | this->source = source; 28 | this->sink = sink; 29 | for (int i = 0; i < n; ++i) { 30 | e[i].clear(); 31 | } 32 | } 33 | 34 | void addEdge(int a, int b, S w) { 35 | e[a].push_back(Edge(b, true, w, e[b].size())); 36 | e[b].push_back(Edge(a, false, -w, e[a].size() - 1)); // TODO 37 | } 38 | 39 | bool mark[MAXN]; 40 | S minw[MAXN]; 41 | int dist[MAXN]; 42 | Edge* prev[MAXN]; 43 | 44 | bool _spfa() { 45 | queue q; 46 | fill(mark, mark + n, false); 47 | fill(minw, minw + n, numeric_limits::max()); 48 | fill(dist, dist + n, 0); 49 | fill(prev, prev + n, (Edge*)NULL); 50 | mark[source] = true; 51 | minw[source] = 0; 52 | 53 | q.push(source); 54 | while (!q.empty()) { 55 | int cur = q.front(); 56 | mark[cur] = false; 57 | q.pop(); 58 | for (typename vector::iterator it = e[cur].begin(); it != e[cur].end(); ++it) { 59 | if (!it->c) { 60 | continue; 61 | } 62 | int v = it->v; 63 | S w = minw[cur] + it->w; 64 | if (minw[v] > w) { // TODO 65 | minw[v] = w; 66 | dist[v] = dist[cur] + 1; 67 | if (dist[v] >= n) { 68 | return false; 69 | } 70 | prev[v] = &*it; 71 | if (!mark[v]) { 72 | mark[v] = true; 73 | q.push(v); 74 | } 75 | } 76 | } 77 | } 78 | return true; 79 | } 80 | 81 | pair gao() { 82 | int sumc = 0; 83 | S sumw = 0; 84 | while (true) { 85 | if (!_spfa()) { 86 | throw NegativeCostCircuitExistsException(); 87 | } else if (minw[sink] == numeric_limits::max()) { 88 | break; 89 | } else { 90 | ++sumc; 91 | sumw += minw[sink]; 92 | 93 | int cur = sink; 94 | while (cur != source) { 95 | Edge* e1 = prev[cur]; 96 | e1->c = false; 97 | Edge* e2 = &e[e1->v][e1->b]; 98 | e2->c = true; 99 | cur = e2->v; 100 | } 101 | } 102 | } 103 | return make_pair(sumc, sumw); 104 | } 105 | }; 106 | 107 | -------------------------------------------------------------------------------- /Graph/Matching/BipartiteMatching/HopcroftKarp.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | struct HopcroftKarp { 8 | int nx, ny; 9 | vector mx, my; 10 | vector > e; 11 | 12 | void init(int nx, int ny) { 13 | this->nx = nx; 14 | this->ny = ny; 15 | mx.resize(nx); 16 | my.resize(ny); 17 | e.clear(); 18 | e.resize(nx); 19 | d.resize(nx); 20 | } 21 | 22 | void add(int a, int b) { 23 | e[a].push_back(b); 24 | } 25 | 26 | vector d; 27 | 28 | int bfs() { 29 | bool ret = false; 30 | queue q; 31 | 32 | for (int i = 0; i < nx; ++i) { 33 | if (mx[i] == -1) { 34 | d[i] = 0; 35 | q.push(i); 36 | } else { 37 | d[i] = -1; 38 | } 39 | } 40 | 41 | while (!q.empty()) { 42 | int v = q.front(); 43 | q.pop(); 44 | for (int w: e[v]) { 45 | if (my[w] == -1) { 46 | ret = true; 47 | } else if (d[my[w]] == -1) { 48 | d[my[w]] = d[v] + 1; 49 | q.push(my[w]); 50 | } 51 | } 52 | } 53 | 54 | return ret; 55 | } 56 | 57 | bool dfs(int v) { 58 | for (int w: e[v]) { 59 | if (my[w] == -1 || (d[my[w]] == d[v] + 1 && dfs(my[w]))) { 60 | mx[v] = w; 61 | my[w] = v; 62 | return true; 63 | } 64 | } 65 | d[v] = -1; 66 | return false; 67 | } 68 | 69 | int gao() { 70 | int ret = 0; 71 | fill(mx.begin(), mx.end(), -1); 72 | fill(my.begin(), my.end(), -1); 73 | while (bfs()) { 74 | for (int i = 0; i < nx; ++i) { 75 | if (mx[i] == -1 && dfs(i)) { 76 | ++ret; 77 | } 78 | } 79 | } 80 | return ret; 81 | } 82 | }; 83 | -------------------------------------------------------------------------------- /Graph/Matching/BipartiteMatching/Hungarian.cpp: -------------------------------------------------------------------------------- 1 | // maximum matchings in bipartite graphs 2 | // maximum cardinality bipartite matching 3 | // O(|V||E|), generally fast 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | using namespace std; 10 | 11 | struct Hungarian { 12 | int nx, ny; 13 | vector mx, my; 14 | vector > e; 15 | 16 | void init(int nx, int ny) { 17 | this->nx = nx; 18 | this->ny = ny; 19 | mx.resize(nx); 20 | my.resize(ny); 21 | e.clear(); 22 | e.resize(nx); 23 | mark.resize(nx); 24 | } 25 | 26 | void add(int a, int b) { 27 | e[a].push_back(b); 28 | } 29 | 30 | // vector is evil!!! 31 | basic_string mark; 32 | 33 | bool augment(int i) { 34 | if (!mark[i]) { 35 | mark[i] = true; 36 | for (vector::const_iterator j = e[i].begin(); j != e[i].end(); ++j) { 37 | if (my[*j] == -1 || augment(my[*j])) { 38 | mx[i] = *j; 39 | my[*j] = i; 40 | return true; 41 | } 42 | } 43 | } 44 | return false; 45 | } 46 | 47 | int gao() { 48 | int ret = 0; 49 | fill(mx.begin(), mx.end(), -1); 50 | fill(my.begin(), my.end(), -1); 51 | for (int i = 0; i < nx; ++i) { 52 | fill(mark.begin(), mark.end(), false); 53 | if (augment(i)) { 54 | ++ret; 55 | } 56 | } 57 | return ret; 58 | } 59 | }; 60 | 61 | -------------------------------------------------------------------------------- /Graph/Matching/BipartiteMatching/t/GTestHelper.cpp: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | 3 | #include 4 | #include 5 | 6 | using namespace boost; 7 | 8 | #define BMTest CONCAT_EX(BM, Test) 9 | 10 | class BMTest: public ::testing::TestWithParam { 11 | protected: 12 | static const int MAXN = 5050; 13 | static BM bm; 14 | }; 15 | 16 | BM BMTest::bm; 17 | 18 | using graph_t = adjacency_list; 19 | using vertex_t = graph_traits::vertex_descriptor; 20 | using mate_map_t = vector_property_map; 21 | using vertex_index_map_t = property_map::type; 22 | 23 | static bool verify_matching(const graph_t& g, mate_map_t mate) { 24 | return maximum_cardinality_matching_verifier< 25 | graph_t, mate_map_t, vertex_index_map_t>::verify_matching( 26 | g, mate, get(vertex_index, g)); 27 | } 28 | 29 | TEST_P_EX(BMTest, Random) { 30 | srand(GetParam()); 31 | 32 | int x = rand(1, MAXN); 33 | int y = rand(1, MAXN); 34 | int n = x + y; 35 | int m = n + rand(1, n) * rand(0, 5); 36 | int ret = 0; 37 | graph_t g; 38 | 39 | bm.init(x, y); 40 | for (int i = 0; i < m; ++i) { 41 | int a = rand(x), b = rand(y); 42 | if (i < x) { 43 | a = i; 44 | } else if (i - x < y) { 45 | b = i - x; 46 | } 47 | bm.add(a, b); 48 | add_edge(a, x + b, g); 49 | } 50 | ret = bm.gao(); 51 | // printf("x=%d, y=%d, m=%d, ans=%d\n", x, y, m, ret); 52 | 53 | mate_map_t mate(n); 54 | bool success = checked_edmonds_maximum_cardinality_matching(g, mate); 55 | int ans = matching_size(g, mate); 56 | auto null = graph_traits::null_vertex; 57 | ASSERT_EQ(ans, ret) << "matching size"; 58 | 59 | for (int i = 0; i < x; ++i) { 60 | mate[i] = bm.mx[i] == -1 ? null() : x + bm.mx[i]; 61 | } 62 | for (int i = 0; i < y; ++i) { 63 | mate[x + i] = bm.my[i] == -1 ? null() : bm.my[i]; 64 | } 65 | success = verify_matching(g, mate); 66 | ASSERT_TRUE(success) << "not a maximum cardinality matching"; 67 | } 68 | 69 | INSTANTIATE_TEST_CASE_P_EX(, BMTest, ::testing::Range(0, 20)); 70 | -------------------------------------------------------------------------------- /Graph/Matching/BipartiteMatching/t/HopcroftKarpGTest.cc: -------------------------------------------------------------------------------- 1 | #include "../HopcroftKarp.cpp" 2 | #define BM HopcroftKarp 3 | #include "GTestHelper.cpp" 4 | -------------------------------------------------------------------------------- /Graph/Matching/BipartiteMatching/t/HungarianGTest.cc: -------------------------------------------------------------------------------- 1 | #include "../Hungarian.cpp" 2 | #define BM Hungarian 3 | #include "GTestHelper.cpp" 4 | -------------------------------------------------------------------------------- /Graph/Matching/GeneralMatching/EdmondsBlossom.rs: -------------------------------------------------------------------------------- 1 | pub struct DisjointSet(Vec); 2 | 3 | impl DisjointSet { 4 | pub fn new(n: usize) -> Self { 5 | DisjointSet((0..n).collect()) 6 | } 7 | 8 | pub fn clear(&mut self) { 9 | self.0.iter_mut().enumerate().for_each(|(i, j)| *j = i); 10 | } 11 | 12 | pub fn getp(&mut self, x: usize) -> usize { 13 | if self.0[x] != x { 14 | self.0[x] = self.getp(self.0[x]); 15 | } 16 | self.0[x] 17 | } 18 | 19 | pub fn setp(&mut self, x: usize, y: usize) -> Option<(usize, usize)> { 20 | let x = self.getp(x); 21 | let y = self.getp(y); 22 | self.0[x] = y; 23 | if x != y { 24 | Some((x, y)) 25 | } else { 26 | None 27 | } 28 | } 29 | } 30 | 31 | pub struct EdmondsBlossom { 32 | e: Vec>, 33 | q: Vec, 34 | ds: DisjointSet, 35 | path: Vec>>, 36 | vmatch: Vec>, 37 | } 38 | 39 | impl EdmondsBlossom { 40 | fn enqueue(&mut self, mut path: Vec, w: usize) { 41 | debug_assert!(self.path[w].is_none()); 42 | path.push(w); 43 | self.path[w] = Some(path); 44 | self.q.push(w); 45 | } 46 | 47 | fn contract_path(&mut self, path: &[usize], p: usize, mut pre: Vec) { 48 | for &v in path.iter().rev() { 49 | let u = self.vmatch[v].unwrap(); 50 | self.ds.setp(u, p); 51 | self.ds.setp(v, p); 52 | if self.path[u].is_none() { 53 | self.enqueue(pre.clone(), u); 54 | } 55 | pre.push(u); 56 | } 57 | } 58 | 59 | fn contract_blossom(&mut self, v: usize, w: usize) { 60 | if self.ds.getp(v) == self.ds.getp(w) { 61 | return; 62 | } 63 | let pv = self.path[v].clone().unwrap(); 64 | let pw = self.path[w].clone().unwrap(); 65 | let lcp = pv.iter().zip(&pw).take_while(|(i, j)| i == j).count(); 66 | let p = pv[lcp - 1]; 67 | self.contract_path(&pv[lcp..], p, pw.clone()); 68 | self.contract_path(&pw[lcp..], p, pv.clone()); 69 | } 70 | 71 | fn augment(&mut self, v: usize, w: usize) { 72 | let path = self.path[v].as_ref().unwrap(); 73 | // eprintln!("augment: {:?} -> {}", path, w); 74 | for pair in path.windows(2) { 75 | if let &[i, j] = pair { 76 | let k = self.vmatch[j].unwrap(); 77 | self.vmatch[i] = Some(k); 78 | self.vmatch[k] = Some(i); 79 | } 80 | } 81 | self.vmatch[v] = Some(w); 82 | self.vmatch[w] = Some(v); 83 | } 84 | 85 | fn bfs(&mut self, root: usize) -> bool { 86 | self.q.clear(); 87 | self.ds.clear(); 88 | self.path.fill(None); 89 | 90 | self.q.push(root); 91 | self.path[root] = Some(vec![root]); 92 | while let Some(v) = self.q.pop() { 93 | let ev = self.e[v].clone(); 94 | for w in ev { 95 | // eprintln!("{} -> {}: {:?}: {:?}", v, w, self.vmatch[w], self.path[w]); 96 | if self.path[w].is_some() { 97 | self.contract_blossom(v, w); 98 | } else if let Some(u) = self.vmatch[w] { 99 | if self.path[u].is_none() { 100 | self.enqueue(self.path[v].clone().unwrap(), u); 101 | } 102 | } else { 103 | self.augment(v, w); 104 | return true; 105 | } 106 | } 107 | } 108 | false 109 | } 110 | 111 | pub fn solve(e: Vec>) -> Vec> { 112 | let n = e.len(); 113 | let mut ret = Self { 114 | e: e, 115 | ds: DisjointSet::new(n), 116 | q: vec![], 117 | path: vec![None; n], 118 | vmatch: vec![None; n], 119 | }; 120 | for i in 0..n { 121 | if ret.vmatch[i].is_none() { 122 | ret.bfs(i); 123 | } 124 | } 125 | ret.vmatch 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /Graph/Matching/GeneralMatching/README.md: -------------------------------------------------------------------------------- 1 | ## EdmondsBlossom 2 | 3 | #### Wiki 4 | 5 | * [Blossom algorithm](https://en.wikipedia.org/wiki/Blossom_algorithm) 6 | 7 | #### Prob 8 | 9 | 1. [Timus1099](https://acm.timus.ru/problem.aspx?space=1&num=1099) 10 | [rs](https://github.com/watashi/AlgoSolution/blob/master/timus/ac/10/1099.rs) 11 | 2. [CF1615G](https://codeforces.com/problemset/problem/1615/G) 12 | rs 13 | 14 | -------------------------------------------------------------------------------- /Graph/Matching/README.md: -------------------------------------------------------------------------------- 1 | ## Covering and Matching 2 | 3 | #### Wiki 4 | 5 | > In any graph without isolated vertices, the sum of the **matching number** 6 | > and the **edge covering number** equals the number of vertices. If there is a 7 | > perfect matching, then both the matching number and the edge cover number are 8 | > |V| / 2. 9 | 10 | > A set is independent if and only if its complement is a vertex cover. The sum 11 | > of the size of a **maximum independent set** α(G) and the size of a **minimum 12 | > vertex cover** β(G) is the number of vertices in the graph. 13 | 14 | > A set is independent if and only if it is a clique in the graph's complement, 15 | > so the two concepts are complementary. 16 | 17 | > In a bipartite graph with no isolated vertices, the number of vertices in a 18 | > **maximum independent set** equals the number of edges in a **minimum edge 19 | > covering**; this is König's theorem. 20 | 21 | -------------------------------------------------------------------------------- /NumberTheory/Matrix/Matrix.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | typedef long long llint; 6 | 7 | struct Matrix { 8 | static const int MAXN = 128; 9 | 10 | int r, c; 11 | llint a[MAXN][MAXN]; 12 | 13 | llint* operator[](int i) { 14 | return a[i]; 15 | } 16 | 17 | const llint* operator[](int i) const { 18 | return a[i]; 19 | } 20 | 21 | void init(int row, int col) { 22 | this->r = row; 23 | this->c = col; 24 | } 25 | 26 | void fill(int row, int col, llint x = 0) { 27 | init(row, col); 28 | for (int i = 0; i < r; ++i) { 29 | ::fill(a[i], a[i] + c, x); 30 | } 31 | } 32 | 33 | void eye(int n, llint x = 1) { 34 | fill(n, n, 0); 35 | for (int i = 0; i < n; ++i) { 36 | a[i][i] = x; 37 | } 38 | } 39 | 40 | void set(const Matrix& o) { 41 | init(o.r, o.c); 42 | for (int i = 0; i < r; ++i) { 43 | copy(o[i], o[i] + c, a[i]); 44 | } 45 | } 46 | }; 47 | 48 | void add(const Matrix& a, const Matrix& b, llint m, Matrix& ret) { 49 | static Matrix c; 50 | c.set(a); 51 | for (int i = 0; i < b.r; ++i) { 52 | for (int j = 0; j < b.c; ++j) { 53 | c[i][j] += b[i][j]; 54 | if (c[i][j] >= m) { 55 | c[i][j] -= m; 56 | } 57 | } 58 | } 59 | ret.set(c); 60 | } 61 | 62 | void mul(const Matrix& a, const Matrix& b, llint m, Matrix& ret) { 63 | static Matrix c; 64 | c.init(a.r, b.c); 65 | for (int i = 0; i < c.r; ++i) { 66 | for (int j = 0; j < c.c; ++j) { 67 | llint x = 0; 68 | for (int k = 0; k < a.c; ++k) { 69 | x += a[i][k] * b[k][j] % m; 70 | } 71 | c[i][j] = x % m; 72 | } 73 | } 74 | ret.set(c); 75 | } 76 | 77 | void pow(const Matrix& a, llint b, llint m, Matrix& ret) { 78 | static Matrix c; 79 | c.set(a); 80 | ret.eye(c.r); 81 | while (b > 0) { 82 | if (b % 2 != 0) { 83 | mul(ret, c, m, ret); 84 | } 85 | b /= 2; 86 | mul(c, c, m, c); 87 | } 88 | } 89 | 90 | -------------------------------------------------------------------------------- /NumberTheory/Matrix/README.md: -------------------------------------------------------------------------------- 1 | ## Matrix.cpp 2 | 3 | **This module is intended and implemented to run fast rather than be more OO.** 4 | 5 | #### Prob 6 | 7 | 1. [CF177G1](http://codeforces.com/contest/177/problem/G1) _This is not a good prob for test this module, as the problem itself is very tough._ 8 | -------------------------------------------------------------------------------- /NumberTheory/ModInverse/ModInverse.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // a * x + b * y = gcd(a, b) >= 0 4 | long long extGcd(long long a, long long b, long long& x, long long& y) { 5 | if (b == 0) { 6 | x = a >= 0 ? 1 : -1; 7 | y = 0; 8 | return abs(a); 9 | } else { 10 | int g = extGcd(b, a % b, y, x); 11 | y -= a / b * x; 12 | return g; 13 | } 14 | } 15 | 16 | // ASSUME: gcd(a, m) == 1 17 | long long modInv(long long a, long long m) { 18 | long long x, y; 19 | extGcd(a, m, x, y); 20 | return (x % m + m) % m; 21 | } 22 | 23 | -------------------------------------------------------------------------------- /NumberTheory/ModInverse/ModInverse.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE GeneralizedNewtypeDeriving #-} 2 | {-# LANGUAGE TypeApplications #-} 3 | 4 | import Data.Word 5 | import Test.QuickCheck 6 | 7 | -- a * x + b * y == gcd a b >= 0 8 | extGcd :: Integral a => a -> a -> (a, a, a) 9 | extGcd a 0 10 | | a >= 0 = (a, 1, 0) 11 | | otherwise = (negate a, -1, 0) 12 | extGcd a b = (g, x, y - a `quot` b * x) 13 | where 14 | (g, y, x) = extGcd b (a `rem` b) 15 | 16 | -- ASSUME: gcd a m == 1 17 | -- a * x `mod` abs m == 1 18 | modInv :: Integral a => a -> a -> a 19 | modInv a m = x 20 | where 21 | (1, x, _) = extGcd a m 22 | 23 | -- ----------------------------------------------------------------------------- 24 | prop_gcd :: Integral a => a -> a -> Bool 25 | prop_gcd a b = gcd a b == g && a * x + b * y == g 26 | where 27 | (g, x, y) = extGcd a b 28 | 29 | newtype I = I Integer 30 | deriving (Eq, Ord, Show, Enum, Num, Real, Integral) 31 | 32 | instance Arbitrary I where 33 | arbitrary = I . product . map toInteger <$> arbitrary @[Large Int] 34 | shrink = shrinkIntegral 35 | 36 | main :: IO () 37 | main = do 38 | check (prop_gcd @I) 39 | check (prop_gcd @(Small Int)) 40 | check (prop_gcd @(Large Word64)) 41 | where 42 | check :: Testable prop => prop -> IO () 43 | check prop = quickCheckWith stdArgs{maxSuccess=1000, maxSize=50} prop 44 | -------------------------------------------------------------------------------- /NumberTheory/ModInverse/ModInverse.rs: -------------------------------------------------------------------------------- 1 | fn gcd(a: i64, b: i64) -> (i64, i64, i64) { 2 | if b != 0 { 3 | let (g, x, y) = gcd(b, a % b); 4 | (g, y, x - a / b * y) 5 | } else if a >= 0 { 6 | (a, 1, 0) 7 | } else { 8 | (-a, -1, 0) 9 | } 10 | } 11 | 12 | fn lcm(a: i64, b: i64) -> i64 { 13 | a / gcd(a, b).0 * b 14 | } 15 | -------------------------------------------------------------------------------- /NumberTheory/ModLinear/ModLinear.java: -------------------------------------------------------------------------------- 1 | // Modular Linear Equations 2 | import java.math.BigInteger; 3 | 4 | public class ModLinear { 5 | // a * g[1] + b * g[2] = g[0] 6 | static BigInteger[] extGcd(BigInteger a, BigInteger b) { 7 | if (b.signum() == 0) { 8 | return new BigInteger[]{a, BigInteger.ONE, BigInteger.ZERO}; 9 | } else { 10 | BigInteger[] g = extGcd(b, a.mod(b)); 11 | return new BigInteger[]{g[0], g[2], g[1].subtract(a.divide(b).multiply(g[2]))}; 12 | } 13 | } 14 | 15 | // x % u[1] = u[0] && x % v[1] = v[0] => x % ret[1] == ret[0] 16 | static BigInteger[] modLinearSys(BigInteger[] u, BigInteger[] v) throws Exception { 17 | BigInteger[] g = extGcd(u[1], v[1]); 18 | BigInteger z = u[0].subtract(v[0]); 19 | if (z.mod(g[0]).signum() != 0) { 20 | throw new Exception("No Solution"); 21 | } else { 22 | z = g[2].multiply(z.divide(g[0])); 23 | BigInteger[] ret = new BigInteger[]{ 24 | v[0].add(v[1].multiply(z)), 25 | u[1].divide(g[0]).multiply(v[1]) 26 | }; 27 | ret[0] = ret[0].mod(ret[1]); 28 | return ret; 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /NumberTheory/Modulo/MInt.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE DataKinds #-} 2 | {-# LANGUAGE GeneralizedNewtypeDeriving #-} 3 | {-# LANGUAGE KindSignatures #-} 4 | 5 | import GHC.TypeLits 6 | 7 | newtype MIntT i (n :: Nat) = MInt i 8 | deriving (Enum, Eq) 9 | 10 | instance Show i => Show (MIntT i n) where 11 | show (MInt a) = show a 12 | 13 | modulo :: (KnownNat n, Num i) => MIntT i n -> i 14 | modulo = fromInteger . natVal 15 | 16 | mint :: (KnownNat n, Integral i) => i -> MIntT i n 17 | mint a = let m = MInt $ a `mod` modulo m in m 18 | 19 | instance (KnownNat n, Integral i) => Num (MIntT i n) where 20 | (+) m@(MInt a) (MInt b) = 21 | let c = a + b in MInt $ if c >= modulo m then c - modulo m else c 22 | (-) m@(MInt a) (MInt b) = 23 | let c = a - b in MInt $ if c >= 0 then c else c + modulo m 24 | (*) m@(MInt a) (MInt b) = MInt $ a * b `rem` modulo m 25 | abs = error "abs" 26 | negate m@(MInt a) = if a == 0 then 0 else MInt $ modulo m - a 27 | signum = error "signum" 28 | fromInteger a = let m = MInt $ fromInteger (a `mod` natVal m) in m 29 | 30 | type MInt = MIntT Int 1000000007 31 | -------------------------------------------------------------------------------- /NumberTheory/Modulo/MInt.rs: -------------------------------------------------------------------------------- 1 | type MIntImpl = u64; 2 | 3 | #[derive(Clone, Copy, Debug, Default)] 4 | pub struct MIntT(MIntImpl); 5 | 6 | impl From for MIntT { 7 | fn from(x: MIntImpl) -> Self { 8 | Self(x % M) 9 | } 10 | } 11 | 12 | impl ops::Add for MIntT { 13 | type Output = Self; 14 | fn add(mut self, rhs: Self) -> Self::Output { 15 | self += rhs; 16 | self 17 | } 18 | } 19 | 20 | impl ops::AddAssign for MIntT { 21 | fn add_assign(&mut self, rhs: Self) { 22 | self.0 += rhs.0; 23 | if self.0 >= M { 24 | self.0 -= M; 25 | } 26 | } 27 | } 28 | 29 | impl ops::Sub for MIntT { 30 | type Output = Self; 31 | fn sub(mut self, rhs: Self) -> Self::Output { 32 | self -= rhs; 33 | self 34 | } 35 | } 36 | 37 | impl ops::SubAssign for MIntT { 38 | fn sub_assign(&mut self, rhs: Self) { 39 | if self.0 < rhs.0 { 40 | self.0 += M; 41 | } 42 | self.0 -= rhs.0; 43 | } 44 | } 45 | 46 | impl ops::Mul for MIntT { 47 | type Output = Self; 48 | fn mul(self, rhs: Self) -> Self::Output { 49 | Self(self.0 * rhs.0 % M) 50 | } 51 | } 52 | 53 | impl ops::MulAssign for MIntT { 54 | fn mul_assign(&mut self, rhs: Self) { 55 | *self = *self * rhs; 56 | } 57 | } 58 | 59 | impl ops::Div for MIntT { 60 | type Output = Self; 61 | fn div(self, rhs: Self) -> Self::Output { 62 | self * rhs.inv() 63 | } 64 | } 65 | 66 | impl ops::DivAssign for MIntT { 67 | fn div_assign(&mut self, rhs: Self) { 68 | *self *= rhs.inv(); 69 | } 70 | } 71 | 72 | impl MIntT { 73 | fn pow(&self, mut b: u64) -> Self { 74 | let mut a = *self; 75 | let mut c = 1.into(); 76 | loop { 77 | if (b & 1) != 0 { 78 | c *= a; 79 | } 80 | b >>= 1; 81 | if b == 0 { 82 | break; 83 | } 84 | a *= a; 85 | } 86 | c 87 | } 88 | 89 | fn inv(&self) -> Self { 90 | self.pow((M - 2) as u64) 91 | } 92 | } 93 | 94 | type MInt = MIntT<1_000_000_007>; 95 | -------------------------------------------------------------------------------- /NumberTheory/NumberTheoreticTransform/NTT.rs: -------------------------------------------------------------------------------- 1 | fn pow_mod(mut a: i64, mut b: i64, m: i64) -> i64 { 2 | let mut c = 1; 3 | while b > 0 { 4 | if b & 1 != 0 { 5 | c = c * a % m; 6 | } 7 | a = a * a % m; 8 | b >>= 1; 9 | } 10 | c 11 | } 12 | 13 | fn is_primitive_root(r: i64, n: i64) -> bool { 14 | let m = n - 1; 15 | (2..) 16 | .take_while(|&i| i * i <= m) 17 | .all(|i| m % i != 0 || (pow_mod(r, i, n) != 1 && pow_mod(r, m / i, n) != 1)) 18 | } 19 | 20 | fn primitive_root(n: i64) -> i64 { 21 | (2..).find(|&i| is_primitive_root(i, n)).unwrap() 22 | } 23 | 24 | pub struct Modulo { 25 | r: i64, 26 | m: i64, 27 | } 28 | 29 | impl Modulo { 30 | pub fn new(m: i64) -> Self { 31 | let r = primitive_root(m); 32 | Self { r: r, m: m } 33 | } 34 | 35 | pub fn pow(&self, a: i64, b: i64) -> i64 { 36 | pow_mod(a, b, self.m) 37 | } 38 | 39 | pub fn inv(&self, a: i64) -> i64 { 40 | self.pow(a, self.m - 2) 41 | } 42 | 43 | fn ntt_impl(a: &[i64], step: usize, r: i64, m: i64) -> Vec { 44 | let n = a.len(); 45 | if n == 1 { 46 | vec![a[0]] 47 | } else { 48 | let rr = r * r % m; 49 | let be = Self::ntt_impl(&a[0..n - step], step * 2, rr, m); 50 | let bo = Self::ntt_impl(&a[step..n], step * 2, rr, m); 51 | let mut w = 1; 52 | be.iter() 53 | .chain(&be) 54 | .zip(bo.iter().chain(&bo)) 55 | .map(|(e, o)| { 56 | let b = (e + w * o) % m; 57 | w = w * r % m; 58 | b 59 | }) 60 | .collect() 61 | } 62 | } 63 | 64 | pub fn ntt(&self, mut a: Vec) -> Vec { 65 | let mut n = 1; 66 | while n < a.len() { 67 | n <<= 1; 68 | } 69 | a.resize(n, 0); 70 | debug_assert!((self.m - 1) % n as i64 == 0); 71 | 72 | let step = (self.m - 1) / n as i64; 73 | let r1 = self.pow(self.r, step); 74 | Self::ntt_impl(&a, 1, r1, self.m) 75 | } 76 | 77 | pub fn intt(&self, a: Vec) -> Vec { 78 | let mut b = Self { 79 | r: self.inv(self.r), 80 | m: self.m, 81 | } 82 | .ntt(a); 83 | let ninv = self.inv(b.len() as i64); 84 | for i in b.iter_mut() { 85 | *i = *i * ninv % self.m; 86 | } 87 | b 88 | } 89 | 90 | pub fn convolution(&self, mut a: Vec, mut b: Vec) -> Vec { 91 | let n = (a.len() + b.len()).max(1) - 1; 92 | a.resize(n, 0); 93 | b.resize(n, 0); 94 | let x = self.ntt(a); 95 | let y = self.ntt(b); 96 | let z = x.into_iter().zip(y).map(|(i, j)| i * j % self.m).collect(); 97 | let mut c = self.intt(z); 98 | while let Some(&0) = c.last() { 99 | c.pop(); 100 | } 101 | c 102 | } 103 | 104 | pub fn poly_pow(&self, mut a: Vec, b: i64) -> Vec { 105 | if a.is_empty() { 106 | a 107 | } else if b == 0 { 108 | vec![1] 109 | } else if b == 1 { 110 | a 111 | } else { 112 | let n = (a.len() - 1) * b as usize + 1; 113 | a.resize(n, 0); 114 | a = self.ntt(a); 115 | for i in a.iter_mut() { 116 | *i = self.pow(*i, b); 117 | } 118 | self.intt(a) 119 | } 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /NumberTheory/NumberTheoreticTransform/README.md: -------------------------------------------------------------------------------- 1 | ## Number-Theoretic Transform (NTT) 2 | 3 | #### Wiki 4 | 5 | * [Fourier transform on finite groups](https://en.wikipedia.org/wiki/Fourier_transform_on_finite_groups) 6 | * [Primitive root modulo n](https://en.wikipedia.org/wiki/Primitive_root_modulo_n) 7 | * [Cooley–Tukey FFT algorithm](https://en.wikipedia.org/wiki/Cooley%E2%80%93Tukey_FFT_algorithm) 8 | 9 | 10 | #### Prob 11 | 12 | 1. [CF1613F](https://codeforces.com/problemset/problem/1613/F) 13 | [rs](https://github.com/watashi/AlgoSolution/blob/master/codeforces/ac/16/1613/F.rs) 14 | 15 | -------------------------------------------------------------------------------- /NumberTheory/Prime/MillerRabin.hs: -------------------------------------------------------------------------------- 1 | import GHC.Integer.GMP.Internals (powModInteger) 2 | 3 | millerRabin :: Integer -> Bool 4 | millerRabin n 5 | | n < 3 = n == 2 6 | | even n = False 7 | | otherwise = all check [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37] -- https://oeis.org/A014233 8 | where 9 | (s, d) = until (odd . snd) (\(i, j) -> (i + 1, j `quot` 2)) (0, n - 1) 10 | check a 11 | | x == 1 = True 12 | | otherwise = any (== n - 1) $ take s $ iterate (\i -> i * i `rem` n) x 13 | where 14 | x = powModInteger a d n 15 | -------------------------------------------------------------------------------- /NumberTheory/Prime/PrimeTable.cpp: -------------------------------------------------------------------------------- 1 | struct PrimeTable { 2 | vector p; 3 | 4 | PrimeTable(int n) { 5 | init(n); 6 | } 7 | 8 | void init(int n) { 9 | p = vector(n, 0); 10 | iota(p.begin(), p.end(), 0); 11 | for (int i = 2; i * i < n; ++i) { 12 | if (p[i] == i) { 13 | for (int j = i * i; j < n; j += i) { 14 | if (p[j] == j) { 15 | p[j] = i; 16 | } 17 | } 18 | } 19 | } 20 | } 21 | 22 | vector> pfactors(int n) const { 23 | vector> d; 24 | while (n > 1) { 25 | int q = p[n], r = 0; 26 | do { 27 | n /= q; 28 | ++r; 29 | } while (n % q == 0); 30 | d.emplace_back(q, r); 31 | } 32 | return d; 33 | } 34 | }; 35 | -------------------------------------------------------------------------------- /NumberTheory/Prime/PrimeTable.rs: -------------------------------------------------------------------------------- 1 | struct PrimeTable(Vec); 2 | 3 | impl PrimeTable { 4 | fn new(n: usize) -> Self { 5 | let mut p = vec![0; cmp::max(2, n)]; 6 | p[1] = 1; 7 | for i in 2..n { 8 | if p[i] == 0 { 9 | p[i] = i; 10 | for j in (i.saturating_mul(i)..n).step_by(i) { 11 | if p[j] == 0 { 12 | p[j] = i; 13 | } 14 | } 15 | } 16 | } 17 | PrimeTable(p) 18 | } 19 | 20 | fn prime_factors(&self, mut n: usize) -> Vec<(usize, u32)> { 21 | let p = &self.0; 22 | debug_assert!(0 < n && n < p.len()); 23 | let mut d: Vec<(usize, u32)> = vec![]; 24 | while n > 1 { 25 | if d.is_empty() || d.last().unwrap().0 != p[n] { 26 | d.push((p[n], 1)); 27 | } else { 28 | d.last_mut().unwrap().1 += 1 29 | } 30 | n /= p[n]; 31 | } 32 | d 33 | } 34 | 35 | fn factors(&self, n: usize) -> Vec { 36 | fn gen(mut i: slice::Iter<(usize, u32)>, mut x: usize, f: &mut Vec) { 37 | match i.next() { 38 | Some(&(p, r)) => { 39 | for _ in 0..r { 40 | gen(i.clone(), x, f); 41 | x *= p; 42 | } 43 | gen(i, x, f); 44 | } 45 | None => { 46 | f.push(x); 47 | } 48 | } 49 | } 50 | let d = self.prime_factors(n); 51 | let mut f = vec![]; 52 | gen(d.iter(), 1, &mut f); 53 | f 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /NumberTheory/Ring/README.md: -------------------------------------------------------------------------------- 1 | ## Ring.cpp 2 | 3 | > In mathematics, a ring is a structure that abstracts and generalizes the basic 4 | > arithmetic operations, specifically the addition and the multiplication. 5 | 6 | #### Wiki 7 | 8 | * [Ring (mathematics)](http://en.wikipedia.org/wiki/Ring_%28mathematics%29) 9 | 10 | #### Prob 11 | 12 | 1. [SRM569-MegaFactorial](http://community.topcoder.com/stat?c=problem_statement&pm=12389) 13 | -------------------------------------------------------------------------------- /NumberTheory/Ring/Ring.cpp: -------------------------------------------------------------------------------- 1 | template 2 | struct Ring: public Base { 3 | typedef typename Base::T T; 4 | 5 | Ring(const Base& base): Base(base) { } 6 | 7 | T pow(T a, I b) const { 8 | T c = this->unit(); 9 | while (b > 0) { 10 | if ((b & 1) != 0) { 11 | c = this->mul(c, a); 12 | } 13 | b >>= 1; 14 | if (b != 0) { 15 | a = this->mul(a, a); 16 | } 17 | } 18 | return c; 19 | } 20 | 21 | T sum(const T& a, I b) const { 22 | if (b == 0) { 23 | return this->zero(); 24 | } else if ((b & 1) != 0) { 25 | --b; 26 | return this->add(sum(a, b), pow(a, b)); 27 | } else { 28 | b >>= 1; 29 | return this->mul(sum(a, b), this->add(this->unit(), pow(a, b))); 30 | } 31 | } 32 | }; 33 | 34 | 35 | /** 36 | * test program 37 | */ 38 | #include 39 | #include "../Matrix/Matrix.cpp" 40 | 41 | using namespace std; 42 | 43 | template 44 | struct ModOp { 45 | typedef I T; 46 | 47 | const T MOD; 48 | 49 | ModOp(const T& mod): MOD(mod) { } 50 | T zero() const { return 0; } 51 | T unit() const { return 1 % MOD; } 52 | T add(const T& lhs, const T& rhs) const { return (lhs + rhs) % MOD; } 53 | T mul(const T& lhs, const T& rhs) const { return (lhs * rhs) % MOD; } 54 | }; 55 | 56 | struct MatrixOp { 57 | typedef Matrix T; 58 | 59 | const int SIZE; 60 | const long long MOD; 61 | 62 | MatrixOp(int size, long long mod): SIZE(size), MOD(mod) { 63 | } 64 | 65 | T zero() const { 66 | T ret; 67 | ret.fill(SIZE, SIZE); 68 | return ret; 69 | } 70 | 71 | T unit() const { 72 | T ret; 73 | ret.eye(SIZE); 74 | return ret; 75 | } 76 | 77 | T add(const T& lhs, const T& rhs) const { 78 | T ret; 79 | ::add(lhs, rhs, MOD, ret); 80 | return ret; 81 | } 82 | 83 | T mul(const T& lhs, const T& rhs) const { 84 | T ret; 85 | ::mul(lhs, rhs, MOD, ret); 86 | return ret; 87 | } 88 | }; 89 | 90 | using namespace std; 91 | 92 | typedef Ring, long long> ModRing; 93 | typedef Ring MatrixRing; 94 | 95 | const int MOD = 1000000007LL; 96 | 97 | int main() { 98 | long long a, b; 99 | ModRing mr = ModRing(ModOp(MOD)); 100 | 101 | cin >> a >> b; 102 | cout << mr.pow(a, b) << endl; 103 | cout << mr.sum(a, b) << endl; 104 | 105 | return 0; 106 | } 107 | -------------------------------------------------------------------------------- /Numeric/FastFourierTransform/FFT.hs: -------------------------------------------------------------------------------- 1 | import Data.Array 2 | import Data.Complex 3 | import Data.Int 4 | import Test.QuickCheck 5 | 6 | -- DITFFT 7 | -- radix-2 ONLY!! 8 | fft, ifft :: RealFloat a => [Complex a] -> [Complex a] 9 | fft x = fft' (-1) x 10 | ifft x = map (/fromIntegral n) y 11 | where 12 | y = fft' 1 x 13 | n = length y 14 | 15 | fft' :: RealFloat a => a -> [Complex a] -> [Complex a] 16 | fft' _ [] = [] 17 | fft' _ [x] = [x] 18 | fft' d x = zipWith3 (\i j k -> i + j * k) (ye ++ ye) (yo ++ yo) $ iterate (*w) 1 19 | where 20 | split [] = ([], []) 21 | split [a] = ([a], [0]) 22 | split (a:b:c) = let (ce, co) = split c in (a:ce, b:co) 23 | (xe, xo) = split x 24 | (ye, yo) = (fft' d xe, fft' d xo) 25 | n = length xe + length xo 26 | w = cis $ 2 * d * pi / fromIntegral n 27 | 28 | -- DFT 29 | dft, idft :: RealFloat a => [Complex a] -> [Complex a] 30 | dft x = dft' (-1) x 31 | idft x = map (/fromIntegral n) y 32 | where 33 | y = dft' 1 x 34 | n = length y 35 | 36 | dft' :: RealFloat a => a -> [Complex a] -> [Complex a] 37 | dft' d x = [sum $ zipWith (\i j -> i * e (j * k)) x [0 ..] | k <- [0 .. n - 1]] 38 | where 39 | n = length x 40 | e i = cis $ 2 * d * pi * fromIntegral i / fromIntegral n 41 | 42 | -- Convolution 43 | convolve :: Integral a => [a] -> [a] -> [a] 44 | convolve a b = map (round . realPart) $ ifft $ zipWith (*) (fft $ pad0 a) (fft $ pad0 b) 45 | where 46 | n = let m = length a + length b in until (>=m) (*2) 1 47 | pad0 x = take n $ map fromIntegral x ++ repeat (0 :: Complex Double) 48 | 49 | -- test 50 | eps :: Double 51 | eps = 1e-6 52 | 53 | (~~) :: [Complex Double] -> [Complex Double] -> Bool 54 | (~~) a b = length a == length b && maximum (map magnitude $ zipWith (-) a b) < eps 55 | 56 | pad :: [Complex Double] -> [Complex Double] 57 | pad x = take n $ x ++ repeat 0 58 | where 59 | n = until (>=length x) (*2) 1 60 | 61 | prop_invertible :: [Complex Double] -> Bool 62 | prop_invertible x = let x' = pad x in (~~ x') $ ifft $ fft x' 63 | 64 | prop_equality :: [Complex Double] -> Bool 65 | prop_equality x = let x' = pad x in fft x' ~~ dft x' 66 | 67 | prop_convolution :: ([Int16], [Int16]) -> Property 68 | prop_convolution (a, b) = 69 | not (null a || null b) ==> 70 | f c' == f (convolve (elems a') (elems b')) 71 | where 72 | da = length a - 1 73 | db = length b - 1 74 | a' = listArray (0, da) $ map toInteger a 75 | b' = listArray (0, db) $ map toInteger b 76 | c' = elems $ accumArray (+) 0 (0, da + db) $ 77 | [(i + j, a'!i * b'!j) | i <- [0 .. da], j <- [0 .. db]] 78 | f = dropWhile (==0) . reverse 79 | 80 | main :: IO () 81 | main = do 82 | quickCheckWith stdArgs{maxSuccess=500} prop_invertible 83 | quickCheckWith stdArgs{maxSuccess=300} prop_invertible 84 | quickCheckWith stdArgs{maxSuccess=200} prop_convolution 85 | -------------------------------------------------------------------------------- /Numeric/FastFourierTransform/README.md: -------------------------------------------------------------------------------- 1 | ## FFT.hs 2 | 3 | #### Wiki 4 | 5 | * [DFT](http://en.wikipedia.org/wiki/Discrete_Fourier_transform) 6 | * [FFT](http://en.wikipedia.org/wiki/Fast_Fourier_transform) 7 | * [Cooley–Tukey algorithm](http://en.wikipedia.org/wiki/Cooley%E2%80%93Tukey_FFT_algorithm) 8 | 9 | -------------------------------------------------------------------------------- /Numeric/LinearSystem/GaussLU.cpp: -------------------------------------------------------------------------------- 1 | const int MAXN = 128; 2 | const double EPS = 1e-10; 3 | 4 | void LU(int n, double a[MAXN][MAXN], int r[MAXN], int c[MAXN]) { 5 | for (int i = 0; i < n; ++i) { 6 | r[i] = c[i] = i; 7 | } 8 | for (int k = 0; k < n; ++k) { 9 | int ii = k, jj = k; 10 | for (int i = k; i < n; ++i) { 11 | for (int j = k; j < n; ++j) { 12 | if (fabs(a[i][j]) > fabs(a[ii][jj])) { 13 | ii = i; 14 | jj = j; 15 | } 16 | } 17 | } 18 | swap(r[k], r[ii]); 19 | swap(c[k], c[jj]); 20 | for (int i = 0; i < n; ++i) { 21 | swap(a[i][k], a[i][jj]); 22 | } 23 | for (int j = 0; j < n; ++j) { 24 | swap(a[k][j], a[ii][j]); 25 | } 26 | if (fabs(a[k][k]) < EPS) { 27 | continue; 28 | } 29 | for (int i = k + 1; i < n; ++i) { 30 | a[i][k] = a[i][k] / a[k][k]; 31 | for (int j = k + 1; j < n; ++j) { 32 | a[i][j] -= a[i][k] * a[k][j]; 33 | } 34 | } 35 | } 36 | } 37 | 38 | void solve(int n, double a[MAXN][MAXN], int r[MAXN], int c[MAXN], double b[MAXN]) { 39 | static double x[MAXN]; 40 | for (int i = 0; i < n; ++i) { 41 | x[i] = b[r[i]]; 42 | } 43 | for (int i = 0; i < n; ++i) { 44 | for (int j = 0; j < i; ++j) { 45 | x[i] -= a[i][j] * x[j]; 46 | } 47 | } 48 | for (int i = n - 1; i >= 0; --i) { 49 | for (int j = n - 1; j > i; --j) { 50 | x[i] -= a[i][j] * x[j]; 51 | } 52 | if (fabs(a[i][i]) >= EPS) { 53 | x[i] /= a[i][i]; 54 | } // else assert(fabs(x[i]) < EPS); 55 | } 56 | for (int i = 0; i < n; ++i) { 57 | b[c[i]] = x[i]; 58 | } 59 | } 60 | 61 | // LU(n - 1, a, r, c); 62 | // solve(n - 1, a, r, c, b); 63 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Library for Algorithm Contest [![Build Status](https://travis-ci.org/watashi/AlgoLib.svg?branch=master)](https://travis-ci.org/watashi/AlgoLib) 2 | 3 | Simple and standalone data structures and algorithms implementations. 4 | Aim to be helpful in algorithm contests. 5 | 6 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'rake' 2 | require 'rake/clean' 3 | 4 | BIN = 't/gtest_main' 5 | SRC = %w(t/gtest/gtest_main.cc t/gtest/gtest-all.cc) 6 | INC = File.join(Dir.pwd, 't/') 7 | 8 | GXX = 'g++' 9 | CXX = ENV['CXX'] || GXX 10 | CXXFLAGS = '-std=c++0x -O2 -Wall -Wextra -Wconversion' 11 | CXXFLAGS << ' -Wno-sign-conversion' if CXX != GXX 12 | CXXFLAGS << ' -D_GLIBCXX_DEBUG' unless ENV['NO_GLIBCXX_DEBUG'] 13 | 14 | CLEAN.include('**/*.o') 15 | CLOBBER.include(BIN) 16 | 17 | rule '.o' => '.cc' do |t| 18 | sh "#{CXX} -I#{INC} #{CXXFLAGS} -c -o #{t.name} #{t.source}" 19 | end 20 | 21 | task :default => [:test] 22 | 23 | task :build do 24 | dir = Rake.original_dir 25 | src = `find "#{dir}" -wholename '*GTest.cc'`.lines.map(&:chomp) 26 | src.each do |i| 27 | dep = [] 28 | dep << "GTestHelper.cpp" 29 | dep << "../#{$1}.cpp" if i =~ /(\w+)GTest.cc$/ 30 | dep = dep.map{|j| File.join(File.dirname(i), j)} 31 | dep = dep.select{|j| File.exists? j} 32 | dep << i 33 | file i.ext('.o') => dep 34 | end 35 | 36 | src += SRC.map{|i| File.join(Dir.pwd, i)} 37 | obj = src.map{|i| i.ext('.o')} 38 | file BIN => obj do 39 | sh "#{CXX} -pthread -o #{BIN} #{obj * ' '}" 40 | end 41 | Rake::Task[BIN.to_sym].invoke 42 | end 43 | 44 | task :test => :build do 45 | sh "ulimit -s unlimited && ./#{BIN} --gtest_shuffle" 46 | end 47 | -------------------------------------------------------------------------------- /String/AhoCorasick/AhoCorasick.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | struct AhoCorasick { 7 | static const int NONE = 0; 8 | static const int MAXN = 1024; 9 | static const int CHARSET = 26; 10 | 11 | int end; 12 | int tag[MAXN]; 13 | int fail[MAXN]; 14 | int trie[MAXN][CHARSET]; 15 | 16 | void init() { 17 | tag[0] = NONE; 18 | fill(trie[0], trie[0] + CHARSET, -1); 19 | end = 1; 20 | } 21 | 22 | int add(int m, const int* s) { 23 | int p = 0; 24 | for (int i = 0; i < m; ++i) { 25 | if (trie[p][*s] == -1) { 26 | tag[end] = NONE; 27 | fill(trie[end], trie[end] + CHARSET, -1); 28 | trie[p][*s] = end++; 29 | } 30 | p = trie[p][*s]; 31 | ++s; 32 | } 33 | return p; 34 | } 35 | 36 | void build() { // !! 37 | queue bfs; 38 | fail[0] = 0; 39 | for (int i = 0; i < CHARSET; ++i) { 40 | if (trie[0][i] != -1) { 41 | fail[trie[0][i]] = 0; 42 | bfs.push(trie[0][i]); 43 | } else { 44 | trie[0][i] = 0; 45 | } 46 | } 47 | while (!bfs.empty()) { 48 | int p = bfs.front(); 49 | tag[p] |= tag[fail[p]]; 50 | bfs.pop(); 51 | for (int i = 0; i < CHARSET; ++i) { 52 | if (trie[p][i] != -1) { 53 | fail[trie[p][i]] = trie[fail[p]][i]; 54 | bfs.push(trie[p][i]); 55 | } else { 56 | trie[p][i] = trie[fail[p]][i]; 57 | } 58 | } 59 | } 60 | } 61 | } ac; 62 | 63 | -------------------------------------------------------------------------------- /String/AhoCorasick/README.md: -------------------------------------------------------------------------------- 1 | ## AhoCorasick.cpp 2 | 3 | #### Wiki 4 | 5 | * [Aho-Corasick string matching algorithm](http://en.wikipedia.org/wiki/Aho%E2%80%93Corasick_string_matching_algorithm) 6 | 7 | #### Prob 8 | 9 | 10 | -------------------------------------------------------------------------------- /String/Matching/KMP.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | template 6 | struct KMP { 7 | vector pat; 8 | vector fail; 9 | 10 | void init(int n, const T s[]) { 11 | vector(s, s + n).swap(pat); 12 | fail.resize(n); 13 | if (n > 0) { 14 | fail[0] = -1; 15 | } 16 | for (int i = 1; i < n; ++i) { 17 | int k = fail[i - 1]; 18 | while (k >= 0 && pat[k + 1] != pat[i]) { 19 | k = fail[k]; 20 | } 21 | fail[i] = (pat[k + 1] == pat[i]) ? k + 1 : -1; 22 | } 23 | } 24 | 25 | vector gao(int m, const T t[]) { 26 | if (pat.empty()) { 27 | return vector(m, 0); 28 | } 29 | vector ret(m); 30 | for (int i = 0, k = 0; i < m; ) { 31 | if (t[i] == pat[k]) { 32 | ++k; 33 | ret[i++] = k; 34 | if (k == (int)pat.size()) { 35 | k = fail[k - 1] + 1; 36 | } 37 | } else if (k > 0) { 38 | k = fail[k - 1] + 1; 39 | } else { 40 | ret[i++] = 0; 41 | } 42 | } 43 | return ret; 44 | } 45 | }; 46 | -------------------------------------------------------------------------------- /String/Matching/KMP.hs: -------------------------------------------------------------------------------- 1 | {-# LANGUAGE FlexibleContexts #-} 2 | {-# LANGUAGE RecordWildCards #-} 3 | 4 | import Prelude hiding (fail) 5 | import Data.Array 6 | 7 | import Data.List 8 | import Test.QuickCheck 9 | 10 | data KMP a = KMP 11 | { pat :: Array Int a 12 | , fail :: Array Int Int 13 | } deriving (Show) 14 | 15 | newKMP :: Eq a => [a] -> KMP a 16 | newKMP a = KMP{..} 17 | where 18 | n = length a 19 | pat = listArray (0, n-1) a 20 | fail = listArray (0, n-1) $ (-1): 21 | [ if pat!(k+1) == e then k+1 else -1 22 | | (i, e) <- tail $ assocs pat 23 | , let k = until (\j -> j < 0 || pat!(j+1) == e) (fail!) (fail!(i-1)) 24 | ] 25 | 26 | runKMP :: Eq a => KMP a -> [a] -> [Int] 27 | runKMP KMP{..} = go 0 28 | where 29 | go _ [] = [] 30 | go k b@(h:t) 31 | | k <= snd (bounds pat) && h == pat!k = let k' = k + 1 in k': go k' t 32 | | k > 0 = let k' = fail!(k-1) + 1 in go k' b 33 | | otherwise = 0: go 0 t 34 | 35 | prop_fail_model :: Eq a => [a] -> Bool 36 | prop_fail_model s = (elems . fail . newKMP $ s) == (map f . tail . inits $ s) 37 | where 38 | f t = head [length i - 1 | i <- tail . tails $ t, i `isPrefixOf` s] 39 | 40 | main :: IO () 41 | main = do 42 | check (prop_fail_model :: [Bool] -> Bool) 43 | check (prop_fail_model :: [Ordering] -> Bool) 44 | check (prop_fail_model :: [Char] -> Bool) 45 | where 46 | check :: Testable prop => prop -> IO () 47 | check = quickCheckWith stdArgs{maxSuccess=1000} 48 | -------------------------------------------------------------------------------- /String/Matching/README.md: -------------------------------------------------------------------------------- 1 | ## String Matching 2 | 3 | ## Knuth-Morris-Pratt (KMP.cpp) 4 | 5 | * Failure function: longest prefix that matches a proper suffix 6 | * `p[0..fail[i]]` is the longest suffix of `p[0..i]`: -1 for empty 7 | 8 | #### Wiki 9 | 10 | * [Knuth–Morris–Pratt algorithm](http://en.wikipedia.org/wiki/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm) 11 | 12 | ## Gusfield's Algorithm (Z.cpp) 13 | 14 | * Z function: longest common prefix of `s` and `s[i..]` 15 | * `s[0..z(i)-1] = s[i...i+z(i)-1]`, or `s[0, z(i)] = s[i, z(i)]` 16 | 17 | -------------------------------------------------------------------------------- /String/Matching/Z.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | template 8 | struct Z { 9 | vector pat; 10 | vector z; 11 | 12 | void init(int n, const T s[]) { 13 | vector(s, s + n).swap(pat); 14 | z.resize(n); 15 | if (n > 0) { 16 | z[0] = n; 17 | } 18 | if (n > 1) { 19 | z[1] = 0; 20 | for (int& w = z[1]; w + 1 < n && pat[w + 1] == pat[w]; ++w) { 21 | } 22 | } 23 | for (int i = 2, k = 1; i < n; ++i) { 24 | int x = k + z[k] - i, y = z[i - k]; 25 | if (y < x) { 26 | z[i] = y; 27 | } else { 28 | z[i] = max(0, x); 29 | for (int& w = z[i]; w + i < n && pat[w + i] == pat[w]; ++w) { 30 | } 31 | k = i; 32 | } 33 | } 34 | } 35 | 36 | vector gao(int m, const T t[]) { 37 | int n = (int)pat.size(); 38 | vector ret(m); 39 | if (m > 0) { 40 | for (int& w = ret[0]; w < n && w < m && t[w] == pat[w]; ++w) { 41 | } 42 | } 43 | for (int i = 1, k = 0; i < m; ++i) { 44 | int x = k + ret[k] - i, y = i - k < n ? z[i - k] : 0; 45 | if (y < x) { 46 | ret[i] = y; 47 | } else { 48 | ret[i] = max(0, x); 49 | for (int& w = ret[i]; w < n && w + i < m && t[w + i] == pat[w]; ++w) { 50 | } 51 | k = i; 52 | } 53 | } 54 | return ret; 55 | } 56 | }; 57 | 58 | -------------------------------------------------------------------------------- /String/Matching/t/KMPGTest.cc: -------------------------------------------------------------------------------- 1 | #include "../KMP.cpp" 2 | #include "common.h" 3 | #include "../../t/GTestHelper.cpp" 4 | 5 | #include 6 | 7 | using namespace std; 8 | 9 | static vector fail(const string& s) { 10 | vector ret(s.length()); 11 | for (int i = 0; i < (int)s.length(); ++i) { 12 | for (int j = 1; ; ++j) { 13 | if (equal(s.c_str() + j, s.c_str() + i + 1, s.c_str())) { 14 | ret[i] = i - j; 15 | break; 16 | } 17 | } 18 | } 19 | return ret; 20 | } 21 | 22 | static vector match(const string& s, const string& t) { 23 | vector ret(s.length()); 24 | for (int i = 0; i < (int)s.length(); ++i) { 25 | for (int j = min((int)t.length(), i + 1); j >= 0; --j) { 26 | if (equal(t.c_str(), t.c_str() + j, s.c_str() + i + 1 - j)) { 27 | ret[i] = j; 28 | break; 29 | } 30 | } 31 | } 32 | return ret; 33 | } 34 | 35 | static KMP kmp; 36 | 37 | class KMPSmallTest: public ::testing::TestWithParam > { 38 | }; 39 | 40 | class KMPLargeTest: public ::testing::TestWithParam { 41 | }; 42 | 43 | TEST(KMPTest, Example) { 44 | vector str = { 45 | "fa", "mi", "fa", "mi", "fa", "mi", "ma", 46 | "fa", "mi", "fa", "mi", "ma", "~"}; 47 | vector pat = {"fa", "mi", "fa", "mi", "ma"}; 48 | vector fail = {-1, -1, 0, 1, -1}; 49 | vector match = {1, 2, 3, 4, 3, 4, 5, 1, 2, 3, 4, 5, 0}; 50 | KMP kmp; 51 | 52 | kmp.init(pat.size(), pat.data()); 53 | ASSERT_EQ(fail, kmp.fail); 54 | ASSERT_EQ(match, kmp.gao(str.size(), str.data())); 55 | } 56 | 57 | TEST_P(KMPSmallTest, Biolerplate) { 58 | string str, pat; 59 | tie(str, pat) = GetParam(); 60 | kmp.init(pat.length(), pat.c_str()); 61 | ASSERT_EQ(fail(pat), kmp.fail); 62 | ASSERT_EQ(match(str, pat), kmp.gao(str.length(), str.c_str())); 63 | } 64 | 65 | TEST_P(KMPLargeTest, Random) { 66 | int param = GetParam(); 67 | string str = randstr(param), pat; 68 | 69 | srand(param); 70 | pat = str; 71 | pat = pat.substr(0, rand(pat.length())); 72 | pat = pat.substr(rand(pat.length())); 73 | 74 | kmp.init(pat.length(), pat.c_str()); 75 | ASSERT_EQ(fail(pat), kmp.fail); 76 | ASSERT_EQ(match(str, pat), kmp.gao(str.length(), str.c_str())); 77 | } 78 | 79 | INSTANTIATE_TEST_CASE_P(, KMPSmallTest, ::testing::ValuesIn(biolerplate2)); 80 | 81 | INSTANTIATE_TEST_CASE_P(, KMPLargeTest, ::testing::Range(0, 10)); 82 | -------------------------------------------------------------------------------- /String/Matching/t/ZGTest.cc: -------------------------------------------------------------------------------- 1 | #include "../Z.cpp" 2 | #include "common.h" 3 | #include "../../t/GTestHelper.cpp" 4 | 5 | #include 6 | 7 | using namespace std; 8 | 9 | static vector zfunc(const string& s) { 10 | vector ret; 11 | for (string::const_iterator i = s.begin(); i != s.end(); ++i) { 12 | ret.push_back(mismatch(i, s.end(), s.begin()).first - i); 13 | } 14 | return ret; 15 | } 16 | 17 | static vector match(const string& s, const string& t) { 18 | vector ret; 19 | for (string::const_iterator i = s.begin(); i != s.end(); ++i) { 20 | ret.push_back(mismatch(i, min(i + t.size(), s.end()), t.begin()).first - i); 21 | } 22 | return ret; 23 | } 24 | 25 | static Z z; 26 | 27 | class ZSmallTest: public ::testing::TestWithParam > { 28 | }; 29 | 30 | class ZLargeTest: public ::testing::TestWithParam { 31 | }; 32 | 33 | TEST(ZTest, Example) { 34 | vector str = { 35 | "fa", "mi", "fa", "mi", "fa", "mi", "ma", 36 | "fa", "mi", "fa", "mi", "ma", "~"}; 37 | vector pat = {"fa", "mi", "fa", "mi", "ma"}; 38 | vector zfunc = {5, 0, 2, 0, 0}; 39 | vector match = {4, 0, 5, 0, 2, 0, 0, 5, 0, 2, 0, 0, 0}; 40 | Z z; 41 | 42 | z.init(pat.size(), pat.data()); 43 | ASSERT_EQ(zfunc, z.z); 44 | ASSERT_EQ(match, z.gao(str.size(), str.data())); 45 | } 46 | 47 | TEST_P(ZSmallTest, Biolerplate) { 48 | string str, pat; 49 | tie(str, pat) = GetParam(); 50 | z.init(pat.length(), pat.c_str()); 51 | ASSERT_EQ(zfunc(pat), z.z); 52 | ASSERT_EQ(match(str, pat), z.gao(str.length(), str.c_str())); 53 | } 54 | 55 | TEST_P(ZLargeTest, Random) { 56 | int param = GetParam(); 57 | string str = randstr(param), pat; 58 | 59 | srand(param); 60 | pat = str; 61 | pat = pat.substr(0, rand(pat.length())); 62 | pat = pat.substr(rand(pat.length())); 63 | 64 | z.init(pat.length(), pat.c_str()); 65 | ASSERT_EQ(zfunc(pat), z.z); 66 | ASSERT_EQ(match(str, pat), z.gao(str.length(), str.c_str())); 67 | } 68 | 69 | INSTANTIATE_TEST_CASE_P(, ZSmallTest, ::testing::ValuesIn(biolerplate2)); 70 | 71 | INSTANTIATE_TEST_CASE_P(, ZLargeTest, ::testing::Range(0, 10)); 72 | -------------------------------------------------------------------------------- /String/Palindrome/Manacher.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | struct Manacher { 6 | vector p; 7 | 8 | template 9 | void init(int n, const T s[]) { 10 | p.resize(max(0, 2 * n - 1)); 11 | for (int i = 0, j = 0, k = 0; i <= 2 * (n - 1); ++i) { 12 | int d = i < k ? min(p[j + j - i], (k - i) / 2) : 0; 13 | int a = i / 2 - d, b = (i + 1) / 2 + d; 14 | while (0 <= a && b < n && s[a] == s[b]) { 15 | --a; 16 | ++b; 17 | ++d; 18 | } 19 | p[i] = d; 20 | if (k < 2 * b - 1) { 21 | j = i; 22 | k = 2 * b - 1; 23 | } 24 | } 25 | } 26 | 27 | // [l, r) 28 | bool isPalindrome(int l, int r) { 29 | int m = l + r - 1; 30 | return m / 2 - p[m] < l; 31 | } 32 | }; 33 | 34 | // brute-force 35 | struct Palindrome { 36 | vector p; 37 | 38 | template 39 | void init(int n, const T s[]) { 40 | p.resize(max(0, 2 * n - 1)); 41 | for (int i = 0; i < (int)p.size(); ++i) { 42 | int a = i / 2, b = (i + 1) / 2, d = 0; 43 | while (0 <= a && b < n && s[a] == s[b]) { 44 | --a; 45 | ++b; 46 | ++d; 47 | } 48 | p[i] = d; 49 | } 50 | } 51 | }; 52 | -------------------------------------------------------------------------------- /String/Palindrome/Manacher.hs: -------------------------------------------------------------------------------- 1 | import Data.Array (assocs, listArray, (!)) 2 | import Test.QuickCheck 3 | 4 | palindrome :: Eq a => [a] -> [(Int, Int, Int)] 5 | palindrome str = [(l, r, go l r) | l <- [1 .. n], r <- [l, l + 1], r <= n] 6 | where 7 | n = length str 8 | a = listArray (1, n) str 9 | go l r 10 | | l < 1 || r > n = 0 11 | | a!l /= a!r = 0 12 | | otherwise = succ $ go (pred l) (succ r) 13 | 14 | manacher :: Eq a => [a] -> [(Int, Int, Int)] 15 | manacher str = [(div i 2, div (i + 1) 2, e) | (i, e) <- assocs b] 16 | where 17 | n = length str 18 | a = listArray (1, n) str 19 | pal l r 20 | | l < 1 || r > n = 0 21 | | a!l /= a!r = 0 22 | | otherwise = succ $ pal (pred l) (succ r) 23 | b = listArray (2, 2*n) $ go 2 (0, 0) 24 | go k (e, c) = if l > n then [] else t: go (k + 1) (e', c') 25 | where 26 | l = div k 2 27 | r = k - l 28 | s = if k <= e then min (b!(2*c-k)) $ 1 + div (e-k) 2 else 0 29 | t = s + pal (l - s) (r + s) 30 | (e', c') = max (e, c) (2 * (r + t - 1), k) 31 | 32 | prob_palindrome_model :: Eq a => [a] -> Bool 33 | prob_palindrome_model s = manacher s == palindrome s 34 | 35 | data Color = Red | Green | Blue deriving (Eq, Show) 36 | instance Arbitrary Color where 37 | arbitrary = elements $ concatMap (uncurry replicate) $ 38 | [(100, Red), (10, Green), (1, Blue)] 39 | 40 | main :: IO () 41 | main = do 42 | check (prob_palindrome_model :: [Bool] -> Bool) 43 | check (prob_palindrome_model :: [Color] -> Bool) 44 | check (prob_palindrome_model :: [Char] -> Bool) 45 | where 46 | check :: Testable prop => prop -> IO () 47 | check = quickCheckWith stdArgs{maxSuccess=1000} 48 | -------------------------------------------------------------------------------- /String/Palindrome/README.md: -------------------------------------------------------------------------------- 1 | ## Longest palindromic substring 2 | 3 | #### Wiki 4 | 5 | * [Longest palindromic substring](http://en.wikipedia.org/wiki/Longest_palindromic_substring) 6 | a.k.a. longest symmetric factor 7 | 8 | ## Manacher.cc 9 | 10 | * Manacher's algorithm: a linear time algorithm to find all maximal palindromic substrings 11 | 12 | ## Manacher.hs 13 | 14 | -------------------------------------------------------------------------------- /String/Palindrome/t/ManacherGTest.cc: -------------------------------------------------------------------------------- 1 | #include "../Manacher.cpp" 2 | #include "common.h" 3 | #include "../../t/GTestHelper.cpp" 4 | 5 | class ManacherSmallTest: public ::testing::TestWithParam { 6 | }; 7 | 8 | class ManacherLargeTest: public ::testing::TestWithParam { 9 | }; 10 | 11 | static Manacher manacher; 12 | static Palindrome palindrome; 13 | 14 | TEST(ManacherTest, Example) { 15 | vector v = {-1, -2, -1, -1, -3, -1, -1, -2}; 16 | vector p = {1, 0, 2, 0, 1, 1, 1, 0, 4, 0, 1, 1, 1, 0, 1}; 17 | manacher.init(v.size(), v.data()); 18 | ASSERT_EQ(p, manacher.p); 19 | } 20 | 21 | TEST_P(ManacherSmallTest, Biolerplate) { 22 | string s = GetParam(); 23 | manacher.init(s.length(), s.c_str()); 24 | palindrome.init(s.length(), s.c_str()); 25 | ASSERT_EQ(palindrome.p, manacher.p); 26 | } 27 | 28 | TEST_P(ManacherLargeTest, Random) { 29 | string s = randstr(GetParam()); 30 | manacher.init(s.length(), s.c_str()); 31 | palindrome.init(s.length(), s.c_str()); 32 | ASSERT_EQ(palindrome.p, manacher.p); 33 | } 34 | 35 | INSTANTIATE_TEST_CASE_P(, ManacherSmallTest, ::testing::ValuesIn(biolerplate)); 36 | 37 | INSTANTIATE_TEST_CASE_P(, ManacherLargeTest, ::testing::Range(0, 10)); 38 | -------------------------------------------------------------------------------- /String/Suffix/README.md: -------------------------------------------------------------------------------- 1 | ## SuffixArrayBase.cpp 2 | 3 | * Complexity: Naive > Simple > Young > Linear 4 | 5 | * LCP: 6 | 7 | sa.init(n, a); 8 | rmq.init(n, sa.height.data()); 9 | 10 | // lcp of a[i..-1] and a[j..-1] 11 | int lcp(int i, int j) { 12 | i = sa.rank[i]; 13 | j = sa.rank[j]; 14 | if (i > j) { 15 | swap(i, j); 16 | } 17 | return i < j ? rmq.value(i + 1, j + 1) : (int)sa.rank.size() - i; 18 | } 19 | 20 | #### Wiki 21 | 22 | * [Suffix array](http://en.wikipedia.org/wiki/Suffix_array) `sa` / `rank` 23 | * [LCP array](http://en.wikipedia.org/wiki/LCP_array) `height` 24 | 25 | ## SuffixArrayNaive.cpp 26 | 27 | * Complexity: O(n^2lgn) + O(n^2) 28 | 29 | ## SuffixArraySimple.cpp 30 | 31 | * Complexity: O(nlg^2(n)) + O(n) 32 | 33 | #### Prob 34 | 35 | 1. [AOJ2444](http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2444) 36 | 37 | ## SuffixArrayYoung.cpp 38 | 39 | * Complexity: O(nlgn) + O(n) 40 | * Radix sort 41 | 42 | ## SuffixArrayLinear.cpp 43 | 44 | * Complexity: O(n) 45 | 46 | -------------------------------------------------------------------------------- /String/Suffix/SuffixArrayBase.cpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | using namespace std; 6 | 7 | struct SuffixArrayBase { 8 | vector sa, rank, height; 9 | 10 | template 11 | void init(int n, const T a[]) { 12 | height.resize(n); 13 | for (int i = 0, z = 0; i < n; ++i) { 14 | if (rank[i] == 0) { 15 | height[0] = z = 0; 16 | } else { 17 | int x = i, y = sa[rank[i] - 1]; 18 | z = max(0, z - 1); 19 | while (x + z < n && y + z < n && a[x + z] == a[y + z]) { 20 | ++z; 21 | } 22 | height[rank[i]] = z; 23 | } 24 | } 25 | } 26 | }; 27 | -------------------------------------------------------------------------------- /String/Suffix/SuffixArrayNaive.cpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "SuffixArrayBase.cpp" 3 | #include 4 | 5 | using namespace std; 6 | 7 | struct SuffixArrayNaive: SuffixArrayBase { 8 | template 9 | void init(int n, const T a[]) { 10 | sa.clear(); 11 | for (int i = 0; i < n; ++i) { 12 | sa.push_back(i); 13 | } 14 | sort(sa.begin(), sa.end(), [=](int i, int j) { 15 | return lexicographical_compare(a + i, a + n, a + j, a + n); 16 | }); 17 | 18 | rank.resize(n); 19 | for (int i = 0; i < n; ++i) { 20 | rank[sa[i]] = i; 21 | } 22 | 23 | height.resize(n); 24 | if (n > 0) { 25 | height[0] = 0; 26 | } 27 | for (int i = 1; i < n; ++i) { 28 | int h = n - max(sa[i], sa[i - 1]); 29 | height[i] = mismatch(a + sa[i], a + sa[i] + h, a + sa[i - 1]).first - (a + sa[i]); 30 | } 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /String/Suffix/SuffixArraySimple.cpp: -------------------------------------------------------------------------------- 1 | #include "SuffixArrayBase.cpp" 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | struct SuffixArraySimple: SuffixArrayBase { 8 | template 9 | void init(int n, const T a[]) { 10 | sa.resize(n); 11 | rank.resize(n); 12 | 13 | for (int i = 0; i < n; ++i) { 14 | rank[i] = a[i]; 15 | } 16 | for (int m = 1; (m == 1 && n == 1) || m < n; m <<= 1) { 17 | vector > suffix(n); 18 | for (int i = 0; i < n; ++i) { 19 | sa[i] = i; 20 | suffix[i] = make_pair(rank[i], 21 | i + m < n ? rank[i + m] : numeric_limits::min()); 22 | } 23 | sort(sa.begin(), sa.end(), [&suffix](int i, int j) { 24 | return suffix[i] < suffix[j]; 25 | }); 26 | for (int i = 0; i < n; ++i) { 27 | if (i == 0 || (suffix[sa[i]] != suffix[sa[i - 1]])) { 28 | rank[sa[i]] = i; 29 | } else { 30 | rank[sa[i]] = rank[sa[i - 1]]; 31 | } 32 | } 33 | } 34 | 35 | SuffixArrayBase::init(n, a); 36 | } 37 | }; 38 | -------------------------------------------------------------------------------- /String/Suffix/SuffixArrayYoung.cpp: -------------------------------------------------------------------------------- 1 | #include "SuffixArrayBase.cpp" 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | 8 | struct SuffixArrayYoung: SuffixArrayBase { 9 | template 10 | void init(int n, const T a[]) { 11 | sa.resize(n); 12 | rank.resize(n); 13 | 14 | vector > assoc(n); 15 | for (int i = 0; i < n; ++i) { 16 | assoc[i] = make_pair(a[i], i); 17 | } 18 | sort(assoc.begin(), assoc.end()); 19 | for (int i = 0; i < n; ++i) { 20 | sa[i] = assoc[i].second; 21 | if (i == 0 || assoc[i].first != assoc[i - 1].first) { 22 | rank[sa[i]] = i; 23 | } else { 24 | rank[sa[i]] = rank[sa[i - 1]]; 25 | } 26 | } 27 | 28 | vector tmp(n), cnt(n); 29 | vector > suffix(n); 30 | for (int m = 1; m < n; m <<= 1) { 31 | // snd 32 | for (int i = 0; i < m; ++i) { 33 | tmp[i] = n - m + i; 34 | } 35 | for (int i = 0, j = m; i < n; ++i) { 36 | if (sa[i] >= m) { 37 | tmp[j++] = sa[i] - m; 38 | } 39 | } 40 | // fst 41 | fill(cnt.begin(), cnt.end(), 0); 42 | for (int i = 0; i < n; ++i) { 43 | ++cnt[rank[i]]; 44 | } 45 | partial_sum(cnt.begin(), cnt.end(), cnt.begin()); 46 | for (int i = n - 1; i >= 0; --i) { 47 | sa[--cnt[rank[tmp[i]]]] = tmp[i]; 48 | } 49 | // 50 | for (int i = 0; i < n; ++i) { 51 | suffix[i] = make_pair(rank[i], 52 | i + m < n ? rank[i + m] : numeric_limits::min()); 53 | } 54 | for (int i = 0; i < n; ++i) { 55 | if (i == 0 || suffix[sa[i]] != suffix[sa[i - 1]]) { 56 | rank[sa[i]] = i; 57 | } else { 58 | rank[sa[i]] = rank[sa[i - 1]]; 59 | } 60 | } 61 | } 62 | 63 | SuffixArrayBase::init(n, a); 64 | } 65 | }; 66 | 67 | -------------------------------------------------------------------------------- /String/Suffix/t/BenchmarkGTest.cc: -------------------------------------------------------------------------------- 1 | #include "common.h" 2 | #include "../../t/GTestHelper.cpp" 3 | #include "../SuffixArrayNaive.cpp" 4 | #include "../SuffixArraySimple.cpp" 5 | #include "../SuffixArrayYoung.cpp" 6 | 7 | static const int LENGTH = 100100; 8 | 9 | template 10 | void test(const string& data) { 11 | T sa; 12 | sa.init(data.size(), data.data()); 13 | } 14 | 15 | template 16 | class SuffixArrayBenchmark: public ::testing::Test { 17 | }; 18 | 19 | TYPED_TEST_CASE_P(SuffixArrayBenchmark); 20 | 21 | TYPED_TEST_P(SuffixArrayBenchmark, Replicate) { 22 | string data(LENGTH, 'a'); 23 | test(data); 24 | } 25 | 26 | TYPED_TEST_P(SuffixArrayBenchmark, Cycle) { 27 | string data(LENGTH, 'a'); 28 | for (int i = 1; i < (int)data.size(); i += 2) { 29 | data[i] = 'b'; 30 | } 31 | test(data); 32 | } 33 | 34 | TYPED_TEST_P(SuffixArrayBenchmark, SmallCharset) { 35 | auto data = randstr(0, 'a', 'c', LENGTH); 36 | test(data); 37 | } 38 | 39 | TYPED_TEST_P(SuffixArrayBenchmark, LargeCharset) { 40 | auto data = randstr(0, ' ', '~', LENGTH); 41 | test(data); 42 | } 43 | 44 | REGISTER_TYPED_TEST_CASE_P(SuffixArrayBenchmark, 45 | Replicate, Cycle, SmallCharset, LargeCharset); 46 | 47 | typedef ::testing::Types SuffixArrayImpl; 48 | 49 | INSTANTIATE_TYPED_TEST_CASE_P(, SuffixArrayBenchmark, SuffixArrayImpl); 50 | -------------------------------------------------------------------------------- /String/Suffix/t/GTestHelper.cpp: -------------------------------------------------------------------------------- 1 | #ifndef _SUFFIX_ARRAY_GTEST_HELPER 2 | #define _SUFFIX_ARRAY_GTEST_HELPER 3 | 4 | #include "common.h" 5 | #include "../../t/GTestHelper.cpp" 6 | #include "../SuffixArrayNaive.cpp" 7 | 8 | #ifndef SUFFIX_ARRAY_NAIVE 9 | #define SUFFIX_ARRAY_NAIVE SuffixArrayNaive 10 | #endif 11 | 12 | #define SMALL_TEST CONCAT_EX(SUFFIX_ARRAY, SmallTest) 13 | #define LARGE_TEST CONCAT_EX(SUFFIX_ARRAY, LargeTest) 14 | 15 | class SMALL_TEST: public ::testing::TestWithParam { 16 | }; 17 | 18 | class LARGE_TEST: public ::testing::TestWithParam { 19 | }; 20 | 21 | static inline void test(const string& s) { 22 | static SUFFIX_ARRAY sa; 23 | static SUFFIX_ARRAY_NAIVE san; 24 | 25 | sa.init(s.size(), s.data()); 26 | san.init(s.size(), s.data()); 27 | ASSERT_EQ(san.sa, sa.sa); 28 | ASSERT_EQ(san.rank, sa.rank); 29 | ASSERT_EQ(san.height, sa.height); 30 | } 31 | 32 | TEST(CONCAT_EX(SUFFIX_ARRAY, Test), Example) { 33 | wstring a = L"abracadabra"; 34 | vector s = {10, 7, 0, 3, 5, 8, 1, 4, 6, 9, 2}; 35 | vector r = {2, 6, 10, 3, 7, 4, 8, 1, 5, 9, 0}; 36 | vector h = {0, 1, 4, 1, 1, 0, 3, 0, 0, 0, 2}; 37 | SUFFIX_ARRAY sa; 38 | 39 | sa.init(a.size(), a.data()); 40 | ASSERT_EQ(s, sa.sa); 41 | ASSERT_EQ(r, sa.rank); 42 | ASSERT_EQ(h, sa.height); 43 | } 44 | 45 | TEST_P_EX(SMALL_TEST, Biolerplate) { 46 | test(GetParam()); 47 | } 48 | 49 | TEST_P_EX(LARGE_TEST, Random) { 50 | test(randstr(GetParam())); 51 | } 52 | 53 | INSTANTIATE_TEST_CASE_P_EX(, SMALL_TEST, ::testing::ValuesIn(biolerplate)); 54 | 55 | INSTANTIATE_TEST_CASE_P_EX(, LARGE_TEST, ::testing::Range(0, 10)); 56 | 57 | #endif 58 | -------------------------------------------------------------------------------- /String/Suffix/t/SuffixArraySimpleGTest.cc: -------------------------------------------------------------------------------- 1 | #include "../SuffixArraySimple.cpp" 2 | #define SUFFIX_ARRAY SuffixArraySimple 3 | #include "GTestHelper.cpp" 4 | -------------------------------------------------------------------------------- /String/Suffix/t/SuffixArrayYoungGTest.cc: -------------------------------------------------------------------------------- 1 | #include "../SuffixArrayYoung.cpp" 2 | #define SUFFIX_ARRAY SuffixArrayYoung 3 | #include "GTestHelper.cpp" 4 | -------------------------------------------------------------------------------- /String/t/GTestHelper.cpp: -------------------------------------------------------------------------------- 1 | #ifndef _STRING_GTEST_HELPER 2 | #define _STRING_GTEST_HELPER 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | 10 | static const vector biolerplate = { 11 | // empty 12 | "", 13 | // singleton 14 | " ", 15 | "~", 16 | // short 17 | "!?", 18 | "zju", 19 | "icpc", 20 | // replicate 21 | "ooooooooooooooooooo", 22 | "eeeeeeeeeeeeeeeeeeee", 23 | // cyclemt19937 24 | "oxooxooxooxoo", 25 | "oxooxooxooxoox", 26 | "oxooxooxooxooxo", 27 | "ACGTACGTACGTACGTACGTACG", 28 | "ACGTACGTACGTACGTACGTACGT", 29 | "010101010101010101010101010101010101010", 30 | "0101010101010101010101010101010101010101", 31 | // ordered 32 | "abcdefghijklmnopqrstuvwxyz", 33 | "zyxwvutsrqponmlkjihgfedcba", 34 | // ... 35 | "ABCCAB", 36 | "BANANA", 37 | "ANPANMAN", 38 | "AABZABZABCZ", 39 | "ABC ABCDAB ABCDABCDABDE", 40 | "ABCDABCDABDE ABCDAB ABC", 41 | }; 42 | 43 | static const vector > biolerplate2 = { 44 | {"", ""}, 45 | {"test", ""}, 46 | {"", "test"}, 47 | {"AABZABZABCZ", "ABZABC"}, 48 | {"oxooxooxooxoo", "ox"}, 49 | {"oxooxooxooxoox", "ooxx"}, 50 | {"ACGTACGTACGTACGTACGTACG", "ACG"}, 51 | {"0101010101010101010101010101010101010101", "10101"}, 52 | {"ABC ABCDAB ABCDABCDABDE", "ABCDABD"}, 53 | {"ABCDABCDABDE ABCDAB ABC", "ABCDABE"}, 54 | }; 55 | 56 | static inline string randstr(int seed, char a = 'A', char b = 'C', int len = 4096) { 57 | mt19937 rng(seed); 58 | string ret(1 + rng() % len, a); 59 | uniform_int_distribution uid(a, b); 60 | generate(ret.begin(), ret.end(), [&]{ return uid(rng); }); 61 | return ret; 62 | } 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /Tree/HeavyLightDecomposition/HeavyLightDecomposition.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | const int MAXM = 16; 8 | const int MAXN = 1 << MAXM; 9 | 10 | // Heavy-Light Decomposition 11 | struct TreeDecomposition { 12 | vector e[MAXN], c[MAXN]; 13 | int s[MAXN]; // subtree size 14 | int p[MAXN]; // parent id 15 | int r[MAXN]; // chain root id 16 | int t[MAXN]; // timestamp, index used in segtree 17 | int ts; 18 | 19 | void dfs_(int v, int f) { 20 | p[v] = f; 21 | s[v] = 1; 22 | for (int i = 0; i < (int)e[v].size(); ++i) { 23 | int w = e[v][i]; 24 | if (w != f) { 25 | dfs_(w, v); 26 | s[v] += s[w]; 27 | } 28 | } 29 | } 30 | 31 | void decomp_(int v, int f, int k) { 32 | t[v] = ts++; 33 | c[k].push_back(v); 34 | r[v] = k; 35 | 36 | int x = 0, y = -1; 37 | for (int i = 0; i < (int)e[v].size(); ++i) { 38 | int w = e[v][i]; 39 | if (w != f) { 40 | if (s[w] > x) { 41 | x = s[w]; 42 | y = w; 43 | } 44 | } 45 | } 46 | if (y != -1) { 47 | decomp_(y, v, k); 48 | } 49 | 50 | for (int i = 0; i < (int)e[v].size(); ++i) { 51 | int w = e[v][i]; 52 | if (w != f && w != y) { 53 | decomp_(w, v, w); 54 | } 55 | } 56 | } 57 | 58 | void init(int n) { 59 | for (int i = 0; i < n; ++i) { 60 | e[i].clear(); 61 | } 62 | } 63 | 64 | void add(int a, int b) { 65 | e[a].push_back(b); 66 | e[b].push_back(a); 67 | } 68 | 69 | void build() { // !! 70 | ts = 0; 71 | dfs_(0, 0); 72 | decomp_(0, 0, 0); 73 | } 74 | } hld; 75 | 76 | -------------------------------------------------------------------------------- /Tree/HeavyLightDecomposition/HeavyLightDecomposition.rs: -------------------------------------------------------------------------------- 1 | pub struct TreeDecomposition { 2 | root: usize, 3 | parent: Vec, 4 | size: Vec, 5 | // invariant: chain[start[i]][index[i]] == i 6 | start: Vec, 7 | index: Vec, 8 | chain: Vec>, 9 | // invariant: id[ts[i]] == i 10 | id: Vec, 11 | ts: Vec, // timestamp, index used in SegTree 12 | } 13 | 14 | pub struct TreeDecompositionIter<'a> { 15 | td: &'a TreeDecomposition, 16 | current: usize, 17 | ancestor: usize, 18 | } 19 | 20 | impl<'a> Iterator for TreeDecompositionIter<'a> { 21 | type Item = (usize, usize); // [a, b) 22 | 23 | fn next(&mut self) -> Option { 24 | if self.current == usize::MAX { 25 | return None; 26 | } 27 | let start = self.td.start[self.current]; 28 | if start == self.td.start[self.ancestor] { 29 | let item = (self.td.ts[self.ancestor], self.td.ts[self.current] + 1); 30 | self.current = usize::MAX; 31 | Some(item) 32 | } else { 33 | let item = (self.td.ts[start], self.td.ts[self.current] + 1); 34 | self.current = self.td.parent[start]; 35 | Some(item) 36 | } 37 | } 38 | } 39 | 40 | // Heavy-Light Decomposition 41 | impl TreeDecomposition { 42 | fn dfs(&mut self, e: &Vec>, v: usize, p: usize) -> usize { 43 | let mut size = 1; 44 | for &w in &e[v] { 45 | if w != p { 46 | size += self.dfs(e, w, v); 47 | } 48 | } 49 | self.parent[v] = p; 50 | self.size[v] = size; 51 | size 52 | } 53 | 54 | fn decomp( 55 | &mut self, 56 | e: &Vec>, 57 | v: usize, 58 | p: usize, 59 | k: usize, 60 | mut ts: usize, 61 | ) -> usize { 62 | self.start[v] = k; 63 | self.index[v] = self.chain[k].len(); 64 | self.chain[k].push(v); 65 | self.ts[v] = ts; 66 | self.id[ts] = v; 67 | ts += 1; 68 | 69 | let mut maxw = v; 70 | for &w in &e[v] { 71 | if w != p && (maxw == v || self.size[w] > self.size[maxw]) { 72 | maxw = w; 73 | } 74 | } 75 | if maxw != v { 76 | ts = self.decomp(e, maxw, v, k, ts); 77 | } 78 | 79 | for &w in &e[v] { 80 | if w != p && w != maxw { 81 | ts = self.decomp(e, w, v, w, ts); 82 | } 83 | } 84 | ts 85 | } 86 | 87 | pub fn new(tree: &Vec>, root: usize) -> Self { 88 | let n = tree.len(); 89 | let mut t = Self { 90 | root: root, 91 | parent: vec![0; n], 92 | size: vec![0; n], 93 | start: vec![0; n], 94 | index: vec![0; n], 95 | chain: vec![vec![]; n], 96 | id: vec![0; n], 97 | ts: vec![0; n], 98 | }; 99 | t.dfs(tree, root, root); 100 | t.decomp(tree, root, root, root, 0); 101 | t 102 | } 103 | 104 | pub fn path_to_root(&self, v: usize) -> TreeDecompositionIter { 105 | TreeDecompositionIter { 106 | td: &self, 107 | current: v, 108 | ancestor: self.root, 109 | } 110 | } 111 | 112 | pub fn path_to_ancestor(&self, v: usize, ancestor: usize) -> TreeDecompositionIter { 113 | debug_assert!(self.lca(v, ancestor) == ancestor); 114 | TreeDecompositionIter { 115 | td: &self, 116 | current: v, 117 | ancestor: ancestor, 118 | } 119 | } 120 | 121 | pub fn lca(&self, a: usize, b: usize) -> usize { 122 | let mut pa = self.path_to_root(a).collect::>(); 123 | let mut pb = self.path_to_root(b).collect::>(); 124 | pa.reverse(); 125 | pb.reverse(); 126 | debug_assert!(pa[0].0 == 0 && pb[0].0 == 0); 127 | let mut i = 1; 128 | while i < pa.len() && i < pb.len() && pa[i].0 == pb[i].0 { 129 | i += 1; 130 | } 131 | i -= 1; 132 | self.id[pa[i].1.min(pb[i].1) - 1] 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /Tree/HeavyLightDecomposition/README.md: -------------------------------------------------------------------------------- 1 | #### Prob 2 | 3 | 1. codechef/JULY12/DGCD.cpp 4 | 2. [CF1633F](https://codeforces.com/problemset/problem/1615/C): 5 | [rs](https://github.com/watashi/AlgoSolution/blob/913d9d47ad3342abf2ccc19368a8a70145c076ac/codeforces/ac/16/1633/F.tutorial.rs) 6 | -------------------------------------------------------------------------------- /Tree/LCA/LCA.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace std; 6 | 7 | const int MAXM = 16; 8 | const int MAXN = 1 << MAXM; 9 | 10 | // LCA 11 | struct LCA { 12 | vector e[MAXN]; 13 | int d[MAXN], p[MAXN][MAXM]; 14 | 15 | void dfs_(int v, int f) { 16 | p[v][0] = f; 17 | for (int i = 1; i < MAXM; ++i) { 18 | p[v][i] = p[p[v][i - 1]][i - 1]; 19 | } 20 | for (int i = 0; i < (int)e[v].size(); ++i) { 21 | int w = e[v][i]; 22 | if (w != f) { 23 | d[w] = d[v] + 1; 24 | dfs_(w, v); 25 | } 26 | } 27 | } 28 | 29 | int up_(int v, int m) { 30 | for (int i = 0; i < MAXM; ++i) { 31 | if (m & (1 << i)) { 32 | v = p[v][i]; 33 | } 34 | } 35 | return v; 36 | } 37 | 38 | int lca(int a, int b) { 39 | if (d[a] > d[b]) { 40 | swap(a, b); 41 | } 42 | b = up_(b, d[b] - d[a]); 43 | if (a == b) { 44 | return a; 45 | } else { 46 | for (int i = MAXM - 1; i >= 0; --i) { 47 | if (p[a][i] != p[b][i]) { 48 | a = p[a][i]; 49 | b = p[b][i]; 50 | } 51 | } 52 | return p[a][0]; 53 | } 54 | } 55 | 56 | void init(int n) { 57 | for (int i = 0; i < n; ++i) { 58 | e[i].clear(); 59 | } 60 | } 61 | 62 | void add(int a, int b) { 63 | e[a].push_back(b); 64 | e[b].push_back(a); 65 | } 66 | 67 | void build() { 68 | d[0] = 0; 69 | dfs_(0, 0); 70 | } 71 | } lca; 72 | 73 | -------------------------------------------------------------------------------- /Tree/LCA/prob: -------------------------------------------------------------------------------- 1 | codechef/JULY12/DGCD.cpp 2 | -------------------------------------------------------------------------------- /Tree/WeightedPathLength/README.md: -------------------------------------------------------------------------------- 1 | ## WeightedPathLength.cpp 2 | 3 | #### Prob 4 | 5 | 1. [CF163E](http://codeforces.com/problemset/problem/163/E) 6 | 7 | -------------------------------------------------------------------------------- /Tree/WeightedPathLength/WeightedPathLength.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | using namespace std; 4 | 5 | /** 6 | \brief Weighted path length from the root 7 | 8 | The structure of tree must be fixed/static 9 | The length of edge can be changed/dynamic 10 | */ 11 | template 12 | struct WeightedPathLength { 13 | int n, m, root; 14 | int id[MAXN][2]; 15 | 16 | /// \see DataStructure/BinaryIndexedTree/BIT.cpp 17 | BIT bit; 18 | 19 | const vector *e; 20 | 21 | void dfs_(int v, int p) { 22 | for (vector::const_iterator it = e[v].begin(); it != e[v].end(); ++it) { 23 | if (*it != p) { 24 | id[*it][0] = m++; 25 | dfs_(*it, v); 26 | id[*it][1] = m++; 27 | } 28 | } 29 | } 30 | 31 | void init(int n, const vector e[MAXN], int root = 0) { 32 | this->n = n; 33 | this->m = 0; 34 | this->root = root; 35 | this->e = e; 36 | dfs_(root, root); 37 | bit.init(m); 38 | } 39 | 40 | /// change weight(\c v, parent(\c v)) to \c w 41 | void update(int v, T w) { 42 | bit.set(id[v][0], w); 43 | bit.set(id[v][1], -w); 44 | } 45 | 46 | /// return the path length from \c root to \c v 47 | T query(int v) { 48 | return v == root ? T() : bit.sum(id[v][0] + 1); 49 | } 50 | }; 51 | -------------------------------------------------------------------------------- /t/common.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include "gtest/gtest.h" 8 | 9 | using namespace std; 10 | 11 | #define CONCAT(a, b) a ## b 12 | #define CONCAT_EX(a, b) CONCAT(a, b) 13 | 14 | #define TEST_EX(a, b) TEST(a, b) 15 | #define TEST_F_EX(a, b) TEST_F(a, b) 16 | #define TEST_P_EX(a, b) TEST_P(a, b) 17 | #define INSTANTIATE_TEST_CASE_P_EX(a, b, c) INSTANTIATE_TEST_CASE_P(a, b, c) 18 | 19 | inline int rand(int n) { 20 | return rand() % n; 21 | } 22 | 23 | inline int rand(int l, int r) { 24 | return l + rand(r - l); 25 | } 26 | 27 | template 28 | T normalize(T v) { 29 | return v; 30 | } 31 | 32 | template 33 | vector normalize(vector v) { 34 | for (T& i: v) { 35 | i = normalize(i); 36 | } 37 | sort(v.begin(), v.end()); 38 | return v; 39 | } 40 | -------------------------------------------------------------------------------- /t/gtest/gtest_main.cc: -------------------------------------------------------------------------------- 1 | // Copyright 2006, Google Inc. 2 | // All rights reserved. 3 | // 4 | // Redistribution and use in source and binary forms, with or without 5 | // modification, are permitted provided that the following conditions are 6 | // met: 7 | // 8 | // * Redistributions of source code must retain the above copyright 9 | // notice, this list of conditions and the following disclaimer. 10 | // * Redistributions in binary form must reproduce the above 11 | // copyright notice, this list of conditions and the following disclaimer 12 | // in the documentation and/or other materials provided with the 13 | // distribution. 14 | // * Neither the name of Google Inc. nor the names of its 15 | // contributors may be used to endorse or promote products derived from 16 | // this software without specific prior written permission. 17 | // 18 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 | // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 | // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 | // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 | // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 | // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 | // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 | // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | 30 | #include 31 | 32 | #include "gtest/gtest.h" 33 | 34 | GTEST_API_ int main(int argc, char **argv) { 35 | std::cout << "Running main() from gtest_main.cc\n"; 36 | 37 | testing::InitGoogleTest(&argc, argv); 38 | return RUN_ALL_TESTS(); 39 | } 40 | --------------------------------------------------------------------------------