├── .circleci └── config.yml ├── .clang-format ├── .drone.yml ├── .github └── workflows │ └── verify.yml ├── .gitmodules ├── .verify-helper ├── config.toml └── timestamps.remote.json ├── README.md ├── expander ├── dummy_include │ ├── algorithm │ ├── array │ ├── bits │ │ └── stdc++.h │ ├── bitset │ ├── cassert │ ├── chrono │ ├── complex │ ├── cstdint │ ├── cstdio │ ├── cstring │ ├── ext │ │ └── pb_ds │ │ │ └── assoc_container.hpp │ ├── iostream │ ├── map │ ├── memory │ ├── numeric │ ├── queue │ ├── random │ ├── set │ ├── string │ ├── unistd.h │ ├── unordered_map │ ├── unordered_set │ ├── vector │ └── x86intrin.h └── expander.py ├── src ├── base.cpp ├── base.hpp ├── bitop.hpp ├── datastructure │ ├── Develop │ │ ├── AA.hpp │ │ ├── AADynamic.hpp │ │ ├── AAMSet.hpp │ │ ├── AASST.hpp │ │ ├── DynamicConnectivity.hpp │ │ ├── EulerTourDirectedTree.hpp │ │ ├── EulerTourTree.hpp │ │ ├── FenwickTree2D.hpp │ │ ├── IMRangeAddTree.hpp │ │ ├── PersistentSST.hpp │ │ ├── RBSStarrySkyTree.hpp │ │ ├── RBSTMSet.hpp │ │ ├── RBSTree.hpp │ │ ├── SplayStarrySkyTree.hpp │ │ ├── SplayTMSet.hpp │ │ └── SplayTree.hpp │ ├── bitvector.hpp │ ├── convexhull.hpp │ ├── dice.hpp │ ├── disjointtable.hpp │ ├── fastset.hpp │ ├── fenwick.hpp │ ├── fenwick2d.hpp │ ├── hashmap.hpp │ ├── hashset.hpp │ ├── linkcuttree.hpp │ ├── linkcuttree_old.hpp │ ├── quickfind.hpp │ ├── radixheap.hpp │ ├── segtree.hpp │ ├── simplequeue.hpp │ ├── smallfind.hpp │ ├── sort_mo.hpp │ ├── sparsetable.hpp │ ├── staticrangesum.hpp │ ├── staticrangeunion.hpp │ ├── toptree.hpp │ ├── unionfind.hpp │ └── wavelet.hpp ├── geo │ ├── 3d.hpp │ ├── circle.hpp │ ├── delaunay.hpp │ ├── graphiccompute.hpp │ ├── intersect.hpp │ ├── polygon.hpp │ ├── primitive.hpp │ └── visualizer.hpp ├── graph │ ├── articulation.hpp │ ├── balancedseparator.hpp │ ├── bidirectedcut.hpp │ ├── bimaching.hpp │ ├── bridge.hpp │ ├── csr.hpp │ ├── dijkstra.hpp │ ├── directedmst.hpp │ ├── dominator.hpp │ ├── hungarian.hpp │ ├── manhattanmst.hpp │ ├── matroidintersection.hpp │ ├── maxclique.hpp │ ├── maxflow.hpp │ ├── mincostflow.hpp │ ├── primitive.hpp │ ├── retrograde.hpp │ ├── scc.hpp │ ├── treedecomp.hpp │ └── twosat.hpp ├── math │ ├── comb.hpp │ ├── dynamicmodint.hpp │ ├── fft.hpp │ ├── frac.hpp │ ├── matrix.hpp │ ├── modint.hpp │ ├── modint61.hpp │ ├── nft.hpp │ ├── nimber.hpp │ ├── poly.hpp │ ├── prime.hpp │ ├── primitive.hpp │ └── qr.hpp ├── string │ ├── ahocorasick.hpp │ ├── manacher.hpp │ ├── mp.hpp │ ├── onlinez.hpp │ ├── rollinghash.hpp │ ├── run.hpp │ ├── suffixarray.hpp │ └── zalgo.hpp ├── tree │ ├── alltree.hpp │ ├── centroid.hpp │ ├── hl.hpp │ └── lca.hpp └── util │ ├── fast_io.hpp │ ├── hash.hpp │ ├── random.hpp │ ├── stack_extend.hpp │ └── stopwatch.hpp └── test-oj ├── aplusb.hpp ├── bimaching.test.cpp ├── comb.test.cpp ├── dbg.test.cpp ├── doublingsa.test.cpp ├── fenwick_2d_rectangle_sum.test.cpp ├── hashmap.test.cpp ├── hashmap_remove.test.cpp ├── hashset.test.cpp ├── hashset_hashmap.test.cpp ├── hl_lca.test.cpp ├── hl_vertex_add_path_sum.test.cpp ├── hl_vertex_add_subtree_sum.test.cpp ├── inv_of_formal_power_series.test.cpp ├── lctree_lca.test.cpp ├── lctree_vertex_add_path_sum.test.cpp ├── max_clique.test.cpp ├── modint.test.cpp ├── modint61.test.cpp ├── nft_convolution.test.cpp ├── nimber.test.cpp ├── number_of_substrings.test.cpp ├── online-zalgo.test.cpp ├── printer.test.cpp ├── rollinghash_zalgo.test.cpp ├── run.test.cpp ├── sais.test.cpp ├── scanner.test.cpp ├── scanner_many_aplusb.test.cpp ├── staticrangesum_rectangle_sum.test.cpp ├── treedecomp_width2.test.cpp ├── unionfind.test.cpp └── zalgo.test.cpp /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | 3 | jobs: 4 | test-debug: 5 | docker: 6 | - image: rikorose/gcc-cmake 7 | steps: 8 | - checkout 9 | - run: 10 | command: | 11 | git submodule update --init --recursive --remote 12 | cd test 13 | mkdir build-debug 14 | cd build-debug 15 | cmake .. -DCMAKE_BUILD_TYPE=Debug 16 | make 17 | make test 18 | test-oj: 19 | docker: 20 | - image: circleci/python:stretch 21 | steps: 22 | - checkout 23 | - run: 24 | command: | 25 | pip3 install --user online-judge-tools 26 | cd test-oj 27 | ./test.sh 28 | 29 | workflows: 30 | version: 2 31 | build: 32 | jobs: 33 | # - test-debug 34 | - test-oj 35 | -------------------------------------------------------------------------------- /.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: 'Chromium' 2 | IndentWidth: 4 3 | AccessModifierOffset: -2 4 | 5 | # for competitive programing 6 | AllowShortFunctionsOnASingleLine: All 7 | AllowShortIfStatementsOnASingleLine: true 8 | AllowShortLoopsOnASingleLine: true 9 | AlwaysBreakTemplateDeclarations: false -------------------------------------------------------------------------------- /.drone.yml: -------------------------------------------------------------------------------- 1 | kind: pipeline 2 | name: default 3 | 4 | steps: 5 | - name: submodules 6 | image: docker:git 7 | commands: 8 | - git submodule update --init --recursive --remote 9 | 10 | - name: test-library-checker 11 | image: python 12 | commands: 13 | - pip install toml 14 | - cd test 15 | - ./library-checker-problems/generate.py ./library-checker-problems/problems.toml -s solutions.toml 16 | 17 | - name: test-debug 18 | image: rikorose/gcc-cmake 19 | commands: 20 | - cd test 21 | - mkdir build-debug 22 | - cd build-debug 23 | - cmake .. -DCMAKE_BUILD_TYPE=Debug 24 | - make 25 | - make test 26 | 27 | - name: test-release 28 | image: rikorose/gcc-cmake 29 | commands: 30 | - cd test 31 | - mkdir build-release 32 | - cd build-release 33 | - cmake .. -DCMAKE_BUILD_TYPE=Release 34 | - make 35 | - make test 36 | 37 | - name: test-relwithdebinfo 38 | image: rikorose/gcc-cmake 39 | commands: 40 | - cd test 41 | - mkdir build-relwithdebinfo 42 | - cd build-relwithdebinfo 43 | - cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo 44 | - make 45 | - make test 46 | -------------------------------------------------------------------------------- /.github/workflows/verify.yml: -------------------------------------------------------------------------------- 1 | name: verify 2 | 3 | on: push 4 | 5 | jobs: 6 | build: 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - uses: actions/checkout@v1 11 | 12 | - name: Set up Python 13 | uses: actions/setup-python@v1 14 | 15 | - name: Install dependencies 16 | run: pip3 install -U online-judge-verify-helper 17 | 18 | - name: Copy files 19 | run: cp -r test-oj/* src/ 20 | 21 | - name: Remove files 22 | run: rm -r test-oj 23 | 24 | - name: Run tests 25 | env: 26 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 27 | YUKICODER_TOKEN: ${{ secrets.YUKICODER_TOKEN }} 28 | GH_PAT: ${{ secrets.GH_PAT }} 29 | run: oj-verify all 30 | 31 | - name: action-slack 32 | uses: 8398a7/action-slack@v3.0.3 33 | with: 34 | status: ${{ job.status }} 35 | env: 36 | SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} 37 | if: always() 38 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "test/googletest"] 2 | path = test/googletest 3 | url = https://github.com/google/googletest 4 | [submodule "test/algorithm-test"] 5 | path = test/algorithm-test 6 | url = https://github.com/yosupo06/algorithm-test 7 | [submodule "test/library-checker-problems"] 8 | path = test/library-checker-problems 9 | url = https://github.com/yosupo06/library-checker-problems 10 | -------------------------------------------------------------------------------- /.verify-helper/config.toml: -------------------------------------------------------------------------------- 1 | [[languages.cpp.environments]] 2 | CXX = "g++" 3 | CXXFLAGS = ["-I", "src", "-Wall", "-Wextra", "-Wshadow", "-Werror", "-std=c++17", "-O2"] -------------------------------------------------------------------------------- /.verify-helper/timestamps.remote.json: -------------------------------------------------------------------------------- 1 | { 2 | "src/bimaching.test.cpp": "2024-02-23 19:31:25 +0900", 3 | "src/comb.test.cpp": "2024-02-23 19:31:25 +0900", 4 | "src/dbg.test.cpp": "2024-02-23 19:31:25 +0900", 5 | "src/doublingsa.test.cpp": "2024-02-23 19:31:25 +0900", 6 | "src/fenwick_2d_rectangle_sum.test.cpp": "2024-02-23 19:31:25 +0900", 7 | "src/hashmap.test.cpp": "2024-02-23 19:31:25 +0900", 8 | "src/hashmap_remove.test.cpp": "2024-02-23 19:31:25 +0900", 9 | "src/hashset.test.cpp": "2024-02-23 19:31:25 +0900", 10 | "src/hashset_hashmap.test.cpp": "2024-02-23 19:31:25 +0900", 11 | "src/hl_lca.test.cpp": "2024-02-23 19:31:25 +0900", 12 | "src/hl_vertex_add_path_sum.test.cpp": "2024-02-23 19:31:25 +0900", 13 | "src/hl_vertex_add_subtree_sum.test.cpp": "2024-02-23 19:31:25 +0900", 14 | "src/inv_of_formal_power_series.test.cpp": "2024-02-23 19:31:25 +0900", 15 | "src/lctree_lca.test.cpp": "2024-02-23 19:31:25 +0900", 16 | "src/lctree_vertex_add_path_sum.test.cpp": "2024-02-23 19:31:25 +0900", 17 | "src/max_clique.test.cpp": "2024-02-23 19:31:25 +0900", 18 | "src/modint.test.cpp": "2024-02-23 19:31:25 +0900", 19 | "src/modint61.test.cpp": "2024-02-23 19:31:25 +0900", 20 | "src/nft_convolution.test.cpp": "2024-02-23 19:31:25 +0900", 21 | "src/nimber.test.cpp": "2024-02-23 19:31:25 +0900", 22 | "src/number_of_substrings.test.cpp": "2024-02-23 19:31:25 +0900", 23 | "src/online-zalgo.test.cpp": "2024-02-23 19:31:25 +0900", 24 | "src/printer.test.cpp": "2024-02-23 19:31:25 +0900", 25 | "src/rollinghash_zalgo.test.cpp": "2024-02-23 19:31:25 +0900", 26 | "src/run.test.cpp": "2024-02-23 19:31:25 +0900", 27 | "src/sais.test.cpp": "2024-02-23 19:31:25 +0900", 28 | "src/scanner.test.cpp": "2024-02-23 19:31:25 +0900", 29 | "src/scanner_many_aplusb.test.cpp": "2024-02-23 19:31:25 +0900", 30 | "src/staticrangesum_rectangle_sum.test.cpp": "2024-02-23 19:31:25 +0900", 31 | "src/treedecomp_width2.test.cpp": "2024-02-23 19:31:25 +0900", 32 | "src/unionfind.test.cpp": "2024-02-23 19:31:25 +0900", 33 | "src/zalgo.test.cpp": "2024-02-23 19:31:25 +0900" 34 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Actions Status](https://github.com/yosupo06/Algorithm/workflows/verify/badge.svg)](https://github.com/yosupo06/Algorithm/actions) 2 | [![GitHub Pages](https://img.shields.io/static/v1?label=GitHub+Pages&message=+&color=brightgreen&logo=github)](https://yosupo06.github.io/Algorithm/) 3 | 4 | # Algorithms 5 | 6 | プログラミングコンテスト(Codeforces, ICPC等)で使用する為のコード断片集です 7 | 8 | C++11で実装されています 9 | -------------------------------------------------------------------------------- /expander/dummy_include/algorithm: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #pragma yosupo_dummy "#include " 3 | -------------------------------------------------------------------------------- /expander/dummy_include/array: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #pragma yosupo_dummy "#include " 3 | -------------------------------------------------------------------------------- /expander/dummy_include/bits/stdc++.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #pragma yosupo_dummy "#include " 3 | -------------------------------------------------------------------------------- /expander/dummy_include/bitset: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #pragma yosupo_dummy "#include " 3 | -------------------------------------------------------------------------------- /expander/dummy_include/cassert: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #pragma yosupo_dummy "#include " 3 | -------------------------------------------------------------------------------- /expander/dummy_include/chrono: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #pragma yosupo_dummy "#include " 3 | -------------------------------------------------------------------------------- /expander/dummy_include/complex: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #pragma yosupo_dummy "#include " 3 | -------------------------------------------------------------------------------- /expander/dummy_include/cstdint: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #pragma yosupo_dummy "#include " 3 | -------------------------------------------------------------------------------- /expander/dummy_include/cstdio: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #pragma yosupo_dummy "#include " 3 | -------------------------------------------------------------------------------- /expander/dummy_include/cstring: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #pragma yosupo_dummy "#include " 3 | -------------------------------------------------------------------------------- /expander/dummy_include/ext/pb_ds/assoc_container.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #pragma yosupo_dummy "#include " 3 | -------------------------------------------------------------------------------- /expander/dummy_include/iostream: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #pragma yosupo_dummy "#include " 3 | -------------------------------------------------------------------------------- /expander/dummy_include/map: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #pragma yosupo_dummy "#include " 3 | -------------------------------------------------------------------------------- /expander/dummy_include/memory: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #pragma yosupo_dummy "#include " 3 | -------------------------------------------------------------------------------- /expander/dummy_include/numeric: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #pragma yosupo_dummy "#include " 3 | -------------------------------------------------------------------------------- /expander/dummy_include/queue: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #pragma yosupo_dummy "#include " 3 | -------------------------------------------------------------------------------- /expander/dummy_include/random: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #pragma yosupo_dummy "#include " 3 | -------------------------------------------------------------------------------- /expander/dummy_include/set: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #pragma yosupo_dummy "#include " 3 | -------------------------------------------------------------------------------- /expander/dummy_include/string: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #pragma yosupo_dummy "#include " 3 | -------------------------------------------------------------------------------- /expander/dummy_include/unistd.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #pragma yosupo_dummy "#include " 3 | -------------------------------------------------------------------------------- /expander/dummy_include/unordered_map: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #pragma yosupo_dummy "#include " 3 | -------------------------------------------------------------------------------- /expander/dummy_include/unordered_set: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #pragma yosupo_dummy "#include " 3 | -------------------------------------------------------------------------------- /expander/dummy_include/vector: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #pragma yosupo_dummy "#include " 3 | -------------------------------------------------------------------------------- /expander/dummy_include/x86intrin.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #pragma yosupo_dummy "#include " 3 | -------------------------------------------------------------------------------- /expander/expander.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import argparse 4 | import re 5 | from os import getenv 6 | from logging import Logger, basicConfig, getLogger 7 | from subprocess import check_call 8 | 9 | logger = getLogger(__name__) # type: Logger 10 | 11 | if __name__ == "__main__": 12 | basicConfig( 13 | level=getenv('LOG_LEVEL', 'INFO'), 14 | format="%(asctime)s %(levelname)s %(name)s : %(message)s" 15 | ) 16 | parser = argparse.ArgumentParser(description='Source Code Combiner') 17 | parser.add_argument('src', help='Source File') 18 | parser.add_argument('out', help='Output File') 19 | args = parser.parse_args() 20 | 21 | 22 | CXX = getenv('CXX', 'g++') 23 | check_call([CXX, args.src, 24 | '-E', '-C', '-P', 25 | '-I/Users/yosupo/Programs/Algorithm/src', 26 | '-nostdlib', 27 | '-I/Users/yosupo/Programs/Algorithm/expander/dummy_include', 28 | '-o', args.out]) 29 | 30 | f = open(args.out, 'r') 31 | pat = re.compile(r'#pragma yosupo_dummy "(.*)"') 32 | new_src = "" 33 | for s in f.readlines(): 34 | res = pat.match(s) 35 | if res: 36 | new_src += res.group(1) + '\n' 37 | else: 38 | new_src += s 39 | f.close() 40 | f = open(args.out, 'w') 41 | f.write(new_src) 42 | f.close() 43 | -------------------------------------------------------------------------------- /src/base.cpp: -------------------------------------------------------------------------------- 1 | #pragma GCC target("avx2,bmi,bmi2,lzcnt,popcnt") 2 | //#pragma GCC optimize("Ofast") 3 | //#undef LOCAL 4 | 5 | #include "yosupo/fastio.hpp" 6 | using namespace yosupo; 7 | 8 | #include "base.hpp" 9 | 10 | Scanner sc = Scanner(stdin); 11 | Printer pr = Printer(stdout); 12 | 13 | int main() { 14 | return 0; 15 | } 16 | -------------------------------------------------------------------------------- /src/base.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | using namespace std; 22 | 23 | using uint = unsigned int; 24 | using ll = long long; 25 | using ull = unsigned long long; 26 | constexpr ll TEN(int n) { return (n == 0) ? 1 : 10 * TEN(n - 1); } 27 | template using V = vector; 28 | template using VV = V>; 29 | 30 | #ifdef LOCAL 31 | 32 | ostream& operator<<(ostream& os, __int128_t x) { 33 | if (x < 0) { 34 | os << "-"; 35 | x *= -1; 36 | } 37 | if (x == 0) { 38 | return os << "0"; 39 | } 40 | string s; 41 | while (x) { 42 | s += char(x % 10 + '0'); 43 | x /= 10; 44 | } 45 | reverse(s.begin(), s.end()); 46 | return os << s; 47 | } 48 | ostream& operator<<(ostream& os, __uint128_t x) { 49 | if (x == 0) { 50 | return os << "0"; 51 | } 52 | string s; 53 | while (x) { 54 | s += char(x % 10 + '0'); 55 | x /= 10; 56 | } 57 | reverse(s.begin(), s.end()); 58 | return os << s; 59 | } 60 | 61 | template 62 | ostream& operator<<(ostream& os, const pair& p); 63 | template ostream& operator<<(ostream& os, const V& v); 64 | template ostream& operator<<(ostream& os, const deque& v); 65 | template 66 | ostream& operator<<(ostream& os, const array& a); 67 | template ostream& operator<<(ostream& os, const set& s); 68 | template 69 | ostream& operator<<(ostream& os, const map& m); 70 | 71 | template 72 | ostream& operator<<(ostream& os, const pair& p) { 73 | return os << "P(" << p.first << ", " << p.second << ")"; 74 | } 75 | 76 | template ostream& operator<<(ostream& os, const V& v) { 77 | os << "["; 78 | bool f = false; 79 | for (auto d : v) { 80 | if (f) os << ", "; 81 | f = true; 82 | os << d; 83 | } 84 | return os << "]"; 85 | } 86 | 87 | template ostream& operator<<(ostream& os, const deque& v) { 88 | os << "["; 89 | bool f = false; 90 | for (auto d : v) { 91 | if (f) os << ", "; 92 | f = true; 93 | os << d; 94 | } 95 | return os << "]"; 96 | } 97 | template 98 | ostream& operator<<(ostream& os, const array& a) { 99 | os << "["; 100 | bool f = false; 101 | for (auto d : a) { 102 | if (f) os << ", "; 103 | f = true; 104 | os << d; 105 | } 106 | return os << "]"; 107 | } 108 | 109 | template ostream& operator<<(ostream& os, const set& s) { 110 | os << "{"; 111 | bool f = false; 112 | for (auto d : s) { 113 | if (f) os << ", "; 114 | f = true; 115 | os << d; 116 | } 117 | return os << "}"; 118 | } 119 | template ostream& operator<<(ostream& os, const multiset& s) { 120 | os << "{"; 121 | bool f = false; 122 | for (auto d : s) { 123 | if (f) os << ", "; 124 | f = true; 125 | os << d; 126 | } 127 | return os << "}"; 128 | } 129 | 130 | template 131 | ostream& operator<<(ostream& os, const map& s) { 132 | os << "{"; 133 | bool f = false; 134 | for (auto p : s) { 135 | if (f) os << ", "; 136 | f = true; 137 | os << p.first << ": " << p.second; 138 | } 139 | return os << "}"; 140 | } 141 | 142 | struct PrettyOS { 143 | ostream& os; 144 | bool first; 145 | 146 | template auto operator<<(T&& x) { 147 | if (!first) os << ", "; 148 | first = false; 149 | os << x; 150 | return *this; 151 | } 152 | }; 153 | template void dbg0(T&&... t) { 154 | (PrettyOS{cerr, true} << ... << t); 155 | } 156 | #define dbg(...) \ 157 | do { \ 158 | cerr << __LINE__ << " : " << #__VA_ARGS__ << " = "; \ 159 | dbg0(__VA_ARGS__); \ 160 | cerr << endl; \ 161 | } while (false); 162 | #else 163 | #define dbg(...) 164 | #endif 165 | -------------------------------------------------------------------------------- /src/bitop.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | // bit op 3 | int popcnt(uint x) { return __builtin_popcount(x); } 4 | int popcnt(ull x) { return __builtin_popcountll(x); } 5 | int bsr(uint x) { return 31 - __builtin_clz(x); } 6 | int bsr(ull x) { return 63 - __builtin_clzll(x); } 7 | int bsf(uint x) { return __builtin_ctz(x); } 8 | int bsf(ull x) { return __builtin_ctzll(x); } 9 | -------------------------------------------------------------------------------- /src/datastructure/Develop/AA.hpp: -------------------------------------------------------------------------------- 1 | struct AA { 2 | using NP = AA*; 3 | int ma; 4 | NP l, r; 5 | int sz, lv; 6 | AA(int ma) : l(nullptr), r(nullptr), sz(1), lv(0), ma(ma) {} 7 | AA(NP l, NP r, int lv) : l(l), r(r), lv(lv) { 8 | update(); 9 | } 10 | void update() { 11 | sz = l->sz + r->sz; 12 | ma = max(l->ma, r->ma); 13 | } 14 | static NP skew(NP n) { 15 | if (n->l == nullptr || n->lv != n->l->lv) return n; 16 | NP L = n->l; 17 | n->l = L->r; 18 | n->update(); 19 | L->r = n; 20 | L->update(); 21 | return L; 22 | } 23 | static NP pull(NP n) { 24 | if (n->r == nullptr || n->lv != n->r->lv) return n; 25 | if (n->r->r == nullptr || n->lv != n->r->r->lv) return n; 26 | NP R = n->r; 27 | n->r = R->l; 28 | n->update(); 29 | R->l = n; 30 | R->lv++; 31 | R->update(); 32 | return R; 33 | } 34 | static NP merge(NP l, NP r) { 35 | if (l == nullptr) return r; 36 | if (r == nullptr) return l; 37 | if (l->lv == r->lv) { 38 | return new AA(l, r, l->lv+1); 39 | } 40 | if (l->lv < r->lv) { 41 | r->l = merge(l, r->l); 42 | r->update(); 43 | return pull(skew(r)); 44 | } else { 45 | l->r = merge(l->r, r); 46 | l->update(); 47 | return pull(skew(l)); 48 | } 49 | } 50 | static pair split(NP n, int k) { 51 | if (n == nullptr) return pair(nullptr, nullptr); 52 | if (n->sz == 1) { 53 | if (k == 0) return pair(nullptr, n); 54 | else return pair(n, nullptr); 55 | } 56 | pair m; 57 | if (k <= n->l->sz) { 58 | m = split(n->l, k); 59 | m.second = merge(m.second, n->r); 60 | } else { 61 | m = split(n->r, k - n->l->sz); 62 | m.first = merge(n->l, m.first); 63 | } 64 | delete n; 65 | return m; 66 | } 67 | static NP insert(NP n, int k, NP m) { 68 | if (n == nullptr) return m; 69 | if (n->sz == 1) { 70 | if (k == 0) return new AA(m, n, 1); 71 | else return new AA(n, m, 1); 72 | } 73 | if (k <= n->l->sz) { 74 | n->l = insert(n->l, k, m); 75 | n->update(); 76 | return pull(skew(n)); 77 | } else { 78 | n->r = insert(n->r, k - n->l->sz, m); 79 | n->update(); 80 | return pull(skew(n)); 81 | } 82 | } 83 | static NP remove(NP n, int k) { 84 | if (n->sz == 1) { 85 | delete n; 86 | return nullptr; 87 | } 88 | NP m; 89 | if (k < n->l->sz) { 90 | m = merge(remove(n->l, k), n->r); 91 | } else { 92 | m = merge(n->l, remove(n->r, k - n->l->sz)); 93 | } 94 | delete n; 95 | return m; 96 | } 97 | }; 98 | -------------------------------------------------------------------------------- /src/datastructure/Develop/AADynamic.hpp: -------------------------------------------------------------------------------- 1 | struct AA { 2 | using NP = AA*; 3 | 4 | int ma, lz; 5 | void init_node() { 6 | ma = lz = 0; 7 | } 8 | void update() { 9 | assert(!lz); 10 | sz = l->sz + r->sz; 11 | ma = max(l->ma, r->ma); 12 | } 13 | void push() { 14 | assert(l && r); 15 | assert(l->sz && r->sz); 16 | if (lz) { 17 | l->lzdata(lz); 18 | r->lzdata(lz); 19 | lz = 0; 20 | } 21 | } 22 | void lzdata(int x) { 23 | ma += x; 24 | lz += x; 25 | } 26 | void add(int a, int b, int x) { 27 | if (b <= 0 || sz <= a) return; 28 | if (a <= 0 && sz <= b) { 29 | lzdata(x); 30 | return; 31 | } 32 | push(); 33 | l->add(a, b, x); 34 | r->add(a - l->sz, b - l->sz, x); 35 | update(); 36 | } 37 | int get(int a, int b) { 38 | if (b <= 0 || sz <= a) return -1; 39 | if (a <= 0 && sz <= b) { 40 | return ma; 41 | } 42 | push(); 43 | return max(l->get(a, b), r->get(a - l->sz, b - l->sz)); 44 | } 45 | 46 | NP l, r; 47 | int sz; int lv; 48 | bool isL; // is last 49 | AA(int sz) : l(nullptr), r(nullptr), sz(sz), lv(0), isL(true) { 50 | init_node(); 51 | } 52 | static NP make_child(NP n, int k) { 53 | n->l = new AA(k); n->r = new AA(n->sz - k); 54 | n->lv = 1; 55 | n->isL = false; 56 | n->push(); 57 | return n; 58 | } 59 | static NP skew(NP n) { 60 | if (n->l == nullptr || n->lv != n->l->lv) return n; 61 | NP L = n->l; 62 | n->l = L->r; 63 | n->update(); 64 | L->r = n; 65 | L->update(); 66 | return L; 67 | } 68 | static NP pull(NP n) { 69 | if (n->r == nullptr || n->lv != n->r->lv) return n; 70 | if (n->r->r == nullptr || n->lv != n->r->r->lv) return n; 71 | NP R = n->r; 72 | n->r = R->l; 73 | n->update(); 74 | R->l = n; 75 | R->lv++; 76 | R->update(); 77 | return R; 78 | } 79 | static NP inscut(NP n, int k) { 80 | if (k == 0 || k == n->sz) return n; 81 | if (n->isL) { 82 | return make_child(n, k); 83 | } 84 | n->push(); 85 | if (k <= n->l->sz) { 86 | n->l = inscut(n->l, k); 87 | n->update(); 88 | return pull(skew(n)); 89 | } else { 90 | n->r = inscut(n->r, k - n->l->sz); 91 | n->update(); 92 | return pull(skew(n)); 93 | } 94 | } 95 | }; 96 | -------------------------------------------------------------------------------- /src/datastructure/Develop/FenwickTree2D.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * Fenwick Tree 2D 3 | */ 4 | template 5 | struct FenwickTree2D { 6 | using D = ll; 7 | FenwickTree seg[N+1]; 8 | 9 | void init() { 10 | for (int i = 0; i <= N; i++) { 11 | seg[i].init(); 12 | } 13 | } 14 | 15 | /// 要素(x, y)にdを加算する 16 | void add(int x, int y, D d) { 17 | x++; 18 | while (x <= N) { 19 | seg[x].add(y, d); 20 | x += x & -x; 21 | } 22 | } 23 | 24 | /// x座標が[0, x) y座標が[0, y)の長方形区間のsum 25 | D sum(int x, int y) { 26 | D s = 0; 27 | while (x > 0) { 28 | s += seg[x].sum(y); 29 | x -= x & -x; 30 | } 31 | return s; 32 | } 33 | 34 | /// x座標が[lx, hx) y座標が[ly, hy)の長方形区間のsum 35 | D sum(int lx, int ly, int hx, int hy) { 36 | return (sum(hx, hy) + sum(lx, ly)) 37 | - (sum(lx, hy) + sum(hx, ly)); 38 | } 39 | }; -------------------------------------------------------------------------------- /src/datastructure/Develop/PersistentSST.hpp: -------------------------------------------------------------------------------- 1 | struct Node { 2 | using NP = const Node*; 3 | 4 | int ma, lz; 5 | 6 | /* 7 | init_node, update, push 8 | */ 9 | void init_node() { 10 | ma = lz = 0; 11 | } 12 | void update() { 13 | ma = max(l->ma, r->ma); 14 | } 15 | void push() { 16 | if (!lz) continue; 17 | auto nl = make(l); 18 | auto nr = make(r); 19 | if (lz) { 20 | nl->lzdata(lz); 21 | nr->lzdata(lz); 22 | lz = 0; 23 | } 24 | l = nl; 25 | r = nr; 26 | } 27 | /// pushはconstに関わらず呼んで良い 28 | void push() const { 29 | const_cast(this)->push(); 30 | } 31 | void lzdata(int x) { 32 | ma += x; 33 | lz += x; 34 | } 35 | 36 | NP add(int a, int b, int x) const { 37 | if (b <= 0 or sz <= a) return this; 38 | if (a <= 0 and sz <= b) { 39 | auto n = make(this); 40 | n->lzdata(x); 41 | return n; 42 | } 43 | push(); 44 | auto n = make(this); 45 | auto n->l = l->add(a, b, x); 46 | auto n->r = r->add(a - sz/2, b - sz/2, x); 47 | n->update(); 48 | return n; 49 | } 50 | int get(int a, int b) const { 51 | if (b <= 0 or sz <= a) return -1; 52 | if (a <= 0 and sz <= b) { 53 | return ma; 54 | } 55 | push(); 56 | return max(l->get(a, b), r->get(a-sz/2, b-sz/2)); 57 | } 58 | 59 | NP l, r; 60 | int sz; 61 | Node() {} 62 | Node(int sz) : sz(sz) { 63 | init_node(); 64 | if (sz == 1) return; 65 | l = new Node(sz/2); 66 | r = new Node(sz - sz/2); 67 | update(); 68 | } 69 | static Node* make(NP x) { 70 | auto n = new Node(); 71 | *n = *x; 72 | return n; 73 | } 74 | }; -------------------------------------------------------------------------------- /src/datastructure/Develop/RBSStarrySkyTree.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | RBSTで書かれたStarry Sky Tree 3 | */ 4 | 5 | struct STree { 6 | using D = ll; 7 | const static D INF = 1LL<<55; 8 | struct Node; 9 | using NP = Node*; 10 | static Node last_d; 11 | static NP last; 12 | struct Node { 13 | NP l, r; 14 | int sz; 15 | D v, mi, lz; 16 | Node(D v) :l(last), r(last), sz(1), v(v), mi(v), lz(0) {} 17 | Node() :l(nullptr), r(nullptr), sz(0) {} //last用 18 | void push() { 19 | assert(this != last); 20 | if (lz) { 21 | if (l->sz) { 22 | l->lzdata(lz); 23 | } 24 | if (r->sz) { 25 | r->lzdata(lz); 26 | } 27 | lz = 0; 28 | } 29 | } 30 | void lzdata(D d) { 31 | v += d; 32 | mi += d; 33 | lz += d; 34 | } 35 | NP update() { 36 | assert(this != last); 37 | sz = 1+l->sz+r->sz; 38 | assert(!lz); 39 | mi = v; 40 | if (l->sz) { 41 | mi = min(mi, l->mi); 42 | } 43 | if (r->sz) { 44 | mi = min(mi, r->mi); 45 | } 46 | return this; 47 | } 48 | D get(int a, int b) { 49 | if (!sz || b <= 0 || sz <= a) return INF; 50 | if (a <= 0 && sz <= b) return mi; 51 | push(); 52 | D res = INF; 53 | if (a <= l->sz && l->sz < b) res = min(res, v); 54 | res = min(res, l->get(a, b)); 55 | res = min(res, r->get(a- l->sz - 1, b- l->sz - 1)); 56 | return res; 57 | } 58 | void add(int a, int b, D x) { 59 | if (!sz || b <= 0 || sz <= a) return; 60 | if (a <= 0 && sz <= b) { 61 | lzdata(x); 62 | return; 63 | } 64 | push(); 65 | l->add(a, b, x); 66 | if (a <= l->sz && l->sz < b) { 67 | v += x; 68 | } 69 | r->add(a- l->sz - 1, b- l->sz - 1, x); 70 | update(); 71 | } 72 | } *n; 73 | 74 | 75 | static NP built(int sz, D d[]) { 76 | if (!sz) return last; 77 | int md = sz/2; 78 | NP x = new Node(d[md]); 79 | x->l = built(md, d); 80 | x->r = built(sz-(md+1), d+(md+1)); 81 | return x->update(); 82 | } 83 | 84 | static uint xor128(){ 85 | static uint x=123456789,y=362436069,z=521288629,w=88675123; 86 | uint t; 87 | t=(x^(x<<11));x=y;y=z;z=w; return( w=(w^(w>>19))^(t^(t>>8)) ); 88 | } 89 | static NP merge(NP l, NP r) { 90 | if (!l->sz) return r; 91 | if (!r->sz) return l; 92 | l->push(); r->push(); 93 | if ((int)(xor128() % (l->sz + r->sz)) < l->sz) { 94 | l->r = merge(l->r, r); 95 | return l->update(); 96 | } else { 97 | r->l = merge(l, r->l); 98 | return r->update(); 99 | } 100 | } 101 | static pair split(NP x, int k) { 102 | if (!x->sz) return {last, last}; 103 | x->push(); 104 | if (k <= x->l->sz) { 105 | auto y = split(x->l, k); 106 | x->l = y.second; 107 | y.second = x->update(); 108 | return y; 109 | } else { 110 | auto y = split(x->r, k- x->l->sz -1); 111 | x->r = y.first; 112 | y.first = x->update(); 113 | return y; 114 | } 115 | } 116 | STree() : n(last) {} 117 | STree(NP n) : n(n) {} 118 | STree(D d) : n(new Node(d)) {} 119 | STree(int sz, D d[]) { 120 | n = built(sz, d); 121 | } 122 | int sz() { 123 | return n->sz; 124 | } 125 | void merge(STree r) { 126 | n = merge(n, r.n); 127 | } 128 | STree split(int k) { 129 | auto u = split(n, k); 130 | n = u.first; 131 | return STree(u.second); 132 | } 133 | void insert(int k, D x) { 134 | auto u = split(n, k); 135 | n = merge(merge(u.first, new Node(x)), u.second); 136 | } 137 | void erase(int k) { 138 | auto u = split(n, k); 139 | n = merge(u.first, split(u.second, 1).second); 140 | } 141 | void add(int l, int r, D x) { 142 | return n->add(l, r, x); 143 | } 144 | D get(int l, int r) { 145 | return n->get(l, r); 146 | } 147 | }; 148 | STree::Node STree::last_d = STree::Node(); 149 | STree::NP STree::last = &last_d; -------------------------------------------------------------------------------- /src/datastructure/Develop/RBSTMSet.hpp: -------------------------------------------------------------------------------- 1 | struct Tree { 2 | using D = ll; 3 | struct Node; 4 | using NP = Node*; 5 | static Node last_d; 6 | static NP last; 7 | struct Node { 8 | NP l, r; 9 | int sz; 10 | D v; 11 | Node(D v) :l(last), r(last), sz(1), v(v) {} 12 | Node() :l(nullptr), r(nullptr), sz(0) {} 13 | void push() { 14 | 15 | } 16 | NP update() { 17 | sz = 1+l->sz+r->sz; 18 | return this; 19 | } 20 | int lb(D a) { 21 | if (!sz) return 0; 22 | if (a <= v) return l->lb(a); 23 | return l->sz + 1 + r->lb(a); 24 | } 25 | int ub(D a) { 26 | if (!sz) return 0; 27 | if (v <= a) return l->sz + 1 + r->ub(a); 28 | return l->ub(a); 29 | } 30 | D get(int k) { 31 | if (k == l->sz) return v; 32 | if (k < l->sz) { 33 | return l->get(k); 34 | } else { 35 | return r->get(k- (l->sz+1)); 36 | } 37 | } 38 | } *n; 39 | 40 | static uint xor128(){ 41 | static uint x=123456789,y=362436069,z=521288629,w=88675123; 42 | uint t; 43 | t=(x^(x<<11));x=y;y=z;z=w; return( w=(w^(w>>19))^(t^(t>>8)) ); 44 | } 45 | static NP merge(NP l, NP r) { 46 | if (!l->sz) return r; 47 | if (!r->sz) return l; 48 | l->push(); r->push(); 49 | if ((int)(xor128() % (l->sz + r->sz)) < l->sz) { 50 | l->r = merge(l->r, r); 51 | return l->update(); 52 | } else { 53 | r->l = merge(l, r->l); 54 | return r->update(); 55 | } 56 | } 57 | static pair split(NP x, int k) { 58 | if (!x->sz) return {last, last}; 59 | x->push(); 60 | if (k <= x->l->sz) { 61 | auto y = split(x->l, k); 62 | x->l = y.second; 63 | y.second = x->update(); 64 | return y; 65 | } else { 66 | auto y = split(x->r, k- x->l->sz -1); 67 | x->r = y.first; 68 | y.first = x->update(); 69 | return y; 70 | } 71 | } 72 | 73 | Tree() : n(last) {} 74 | Tree(NP n) : n(n) {} 75 | int sz() { 76 | return n->sz; 77 | } 78 | void merge(Tree r) { 79 | n = merge(n, r.n); 80 | } 81 | Tree split(int k) { 82 | auto u = split(n, k); 83 | n = u.first; 84 | return Tree(u.second); 85 | } 86 | void insert(D v) { 87 | auto u = split(n, lb(v)); 88 | n = merge(merge(u.first, new Node(v)), u.second); 89 | } 90 | void erase(D v) { 91 | assert(count(v)); 92 | auto u = split(n, lb(v)); 93 | n = merge(u.first, split(u.second, 1).second); 94 | } 95 | int count(D v) { 96 | return ub(v) - lb(v); 97 | } 98 | int lb(D v) { 99 | return n->lb(v); 100 | } 101 | int ub(D v) { 102 | return n->ub(v); 103 | } 104 | D get(int k) { 105 | return n->get(k); 106 | } 107 | }; 108 | Tree::Node Tree::last_d = Tree::Node(); 109 | Tree::NP Tree::last = &last_d; -------------------------------------------------------------------------------- /src/datastructure/Develop/RBSTree.hpp: -------------------------------------------------------------------------------- 1 | struct NTree { 2 | using D = ll; 3 | struct Node; 4 | using NP = Node*; 5 | static Node last_d; 6 | static NP last; 7 | struct Node { 8 | NP l, r; 9 | int sz; 10 | D v; 11 | Node(D v) :l(last), r(last), sz(1), v(v) {} 12 | Node() :l(nullptr), r(nullptr), sz(0) {} //last用 13 | void push() { 14 | assert(this != last); 15 | } 16 | NP update() { 17 | assert(this != last); 18 | sz = 1+l->sz+r->sz; 19 | return this; 20 | } 21 | D get(int a) { 22 | assert(0 <= a && a < sz); 23 | push(); 24 | if (a < l->sz) { 25 | return l->get(a); 26 | } else if (a == l->sz) { 27 | return v; 28 | } else { 29 | return r->get(a- (l->sz+1)); 30 | } 31 | } 32 | } *n; 33 | 34 | 35 | static NP built(int sz, D d[]) { 36 | if (!sz) return last; 37 | int md = sz/2; 38 | NP x = new Node(d[md]); 39 | x->l = built(md, d); 40 | x->r = built(sz-(md+1), d+(md+1)); 41 | return x->update(); 42 | } 43 | 44 | static uint xor128(){ 45 | static uint x=123456789,y=362436069,z=521288629,w=88675123; 46 | uint t; 47 | t=(x^(x<<11));x=y;y=z;z=w; return( w=(w^(w>>19))^(t^(t>>8)) ); 48 | } 49 | static NP merge(NP l, NP r) { 50 | if (!l->sz) return r; 51 | if (!r->sz) return l; 52 | l->push(); r->push(); 53 | if ((int)(xor128() % (l->sz + r->sz)) < l->sz) { 54 | l->r = merge(l->r, r); 55 | return l->update(); 56 | } else { 57 | r->l = merge(l, r->l); 58 | return r->update(); 59 | } 60 | } 61 | static pair split(NP x, int k) { 62 | if (!x->sz) return {last, last}; 63 | x->push(); 64 | if (k <= x->l->sz) { 65 | auto y = split(x->l, k); 66 | x->l = y.second; 67 | y.second = x->update(); 68 | return y; 69 | } else { 70 | auto y = split(x->r, k- x->l->sz -1); 71 | x->r = y.first; 72 | y.first = x->update(); 73 | return y; 74 | } 75 | } 76 | NTree() : n(last) {} 77 | NTree(NP n) : n(n) {} 78 | NTree(D d) : n(new Node(d)) {} 79 | NTree(int sz, D d[]) { 80 | n = built(sz, d); 81 | } 82 | int sz() { 83 | return n->sz; 84 | } 85 | void merge(NTree r) { 86 | n = merge(n, r.n); 87 | } 88 | NTree split(int k) { 89 | auto u = split(n, k); 90 | n = u.first; 91 | return NTree(u.second); 92 | } 93 | void insert(int k, D x) { 94 | auto u = split(n, k); 95 | n = merge(merge(u.first, new Node(x)), u.second); 96 | } 97 | void erase(int k) { 98 | auto u = split(n, k); 99 | n = merge(u.first, split(u.second, 1).second); 100 | } 101 | D get(int l) { 102 | return n->get(l); 103 | } 104 | }; 105 | NTree::Node NTree::last_d = NTree::Node(); 106 | NTree::NP NTree::last = &last_d; -------------------------------------------------------------------------------- /src/datastructure/Develop/SplayTMSet.hpp: -------------------------------------------------------------------------------- 1 | struct Tree { 2 | using D = int; 3 | struct Node; 4 | using NP = Node*; 5 | static Node last_d; 6 | static NP last, la; 7 | struct Node { 8 | NP p, l, r; 9 | int sz; 10 | D v; 11 | Node(D v) :p(nullptr), l(last), r(last), sz(1), v(v) {} 12 | Node(NP p, NP l, NP r, int sz = 0) : p(p), l(l), r(r), sz(sz) {} 13 | bool is_root() { 14 | return p == nullptr; 15 | } 16 | void rotr() { 17 | NP q = p, qq = q->p; 18 | q->l = r; r->p = q; 19 | r = q; q->p = this; 20 | q->update(); update(); 21 | if ((p = qq)) { 22 | if (qq->l == q) qq->l = this; 23 | if (qq->r == q) qq->r = this; 24 | qq->update(); 25 | } 26 | } 27 | void rotl() { 28 | NP q = p, qq = q->p; 29 | q->r = l; l->p = q; 30 | l = q; q->p = this; 31 | q->update(); update(); 32 | if ((p = qq)) { 33 | if (qq->l == q) qq->l = this; 34 | if (qq->r == q) qq->r = this; 35 | qq->update(); 36 | } 37 | } 38 | void splay() { 39 | assert(this != last); 40 | while (!is_root()) { 41 | NP q = p; 42 | if (q->is_root()) { 43 | if (q->l == this) rotr(); 44 | else rotl(); 45 | continue; 46 | } 47 | NP r = q->p; 48 | if (r->l == q) { 49 | if (q->l == this) {q->rotr(); rotr();} 50 | else {rotl(); rotr();} 51 | } else { 52 | if (q->r == this) {q->rotl(); rotl();} 53 | else {rotr(); rotl();} 54 | } 55 | } 56 | } 57 | void push() { 58 | 59 | } 60 | NP update() { 61 | if (this == last) return this; 62 | sz = 1+l->sz+r->sz; 63 | return this; 64 | } 65 | } *n; 66 | static NP merge(NP l, NP r) { 67 | if (l == last) { 68 | return r; 69 | } 70 | while (l->r != last) { 71 | l = l->r; 72 | } 73 | l->splay(); 74 | l->r = r; 75 | r->p = l; 76 | return l->update(); 77 | } 78 | static pair split(NP x, int k) { 79 | assert(0 <= k && k <= x->sz); 80 | if (k == x->sz) { 81 | return {x, last}; 82 | } 83 | while (k != x->l->sz) { 84 | if (k < x->l->sz) { 85 | x = x->l; 86 | } else { 87 | k -= x->l->sz+1; 88 | x = x->r; 89 | } 90 | } 91 | 92 | x->splay(); 93 | NP l = x->l; 94 | l->p = NULL; 95 | x->l = last; 96 | return {l, x->update()}; 97 | } 98 | 99 | Tree() : n(last) {} 100 | Tree(NP n) : n(n) {} 101 | int sz() { 102 | return n->sz; 103 | } 104 | void insert(int k, D v) { 105 | auto u = split(n, k); 106 | n = merge(merge(u.first, new Node(v)), u.second); 107 | } 108 | void erase(int k) { 109 | auto u = split(n, k); 110 | n = merge(u.first, split(u.second, 1).second); 111 | } 112 | int getc(int k) { 113 | auto u = split(n, k); 114 | int res = u.second->v; 115 | n = merge(u.first, u.second); 116 | return res; 117 | } 118 | }; 119 | Tree::Node Tree::last_d = Tree::Node(NULL, NULL, NULL, 0); 120 | Tree::NP Tree::last = &last_d; 121 | Tree::NP Tree::la; 122 | -------------------------------------------------------------------------------- /src/datastructure/convexhull.hpp: -------------------------------------------------------------------------------- 1 | template 2 | struct ConvexHull { 3 | using L = array; 4 | 5 | bool que_incr; 6 | ConvexHull(bool _que_incr) : que_incr(_que_incr) {} 7 | 8 | deque lines; 9 | // can remove mid? 10 | static bool is_need(L mid, L left, L right) { 11 | assert(left[0] <= mid[0] && mid[0] <= right[0]); 12 | return (right[0]-mid[0])*(left[1]-mid[1]) < (mid[0]-left[0])*(mid[1]-right[1]); 13 | } 14 | //work with 2^(60 + 64) 15 | /*static bool is_need(L mid, L left, L right) { 16 | assert(left[0] <= mid[0] && mid[0] <= right[0]); 17 | ll a = (right[0]-mid[0]), b = (left[1]-mid[1]), c = (mid[0]-left[0]), d = (mid[1]-right[1]); 18 | long double x = (long double)(a) * b - (long double)(c) * d; 19 | if (abs(x) > (1LL << 60)) return x < 0; 20 | int fl = b < 0, fr = d < 0; 21 | if (fl != fr) return fl == 1; 22 | ull z = ull(a) * ull(abs(b)) - ull(c) * ull(abs(d)); 23 | if (fl == 0) return (1ULL << 63) < z; 24 | return z < (1ULL << 63); 25 | }*/ 26 | 27 | void insert_front(L l) { 28 | if (lines.empty()) { 29 | lines.push_front(l); 30 | return; 31 | } 32 | assert(l[0] <= lines[0][0]); 33 | if (l[0] == lines[0][0]) { 34 | if (l[1] <= lines[0][1]) return; 35 | lines.pop_front(); 36 | } 37 | while (lines.size() >= 2 && !is_need(lines.front(), l, lines[1])) { 38 | lines.pop_front(); 39 | } 40 | lines.push_front(l); 41 | } 42 | void insert_back(L l) { 43 | if (lines.empty()) { 44 | lines.push_back(l); 45 | return; 46 | } 47 | assert(lines.back()[0] <= l[0]); 48 | if (lines.back()[0] == l[0]) { 49 | if (l[1] <= lines.back()[1]) return; 50 | lines.pop_back(); 51 | } 52 | while (lines.size() >= 2 && !is_need(lines.back(), lines[lines.size()-2], l)) { 53 | lines.pop_back(); 54 | } 55 | lines.push_back(l); 56 | } 57 | /** 58 | Insert line 59 | line's degree must be minimum or maximum 60 | */ 61 | void insert_line(L line) { 62 | if (lines.empty()) { 63 | lines.push_back(line); 64 | return; 65 | } 66 | if (line[0] <= lines[0][0]) insert_front(line); 67 | else if (lines.back()[0] <= line[0]) insert_back(line); 68 | else assert(false); //line's degree must be minimum or maximum 69 | } 70 | /// get maximum y 71 | T b_x; 72 | T first = true; 73 | T max_y(T x) { 74 | assert(lines.size()); 75 | auto value = [&](L l) { return l[0] * x + l[1]; }; 76 | if (que_incr) { 77 | assert(first || b_x <= x); 78 | first = false; b_x = x; 79 | while (lines.size() >= 2 && 80 | value(lines[0]) <= value(lines[1])) { 81 | lines.pop_front(); 82 | } 83 | return value(lines.front()); 84 | } else { 85 | assert(first || x <= b_x); 86 | first = false; b_x = x; 87 | while (lines.size() >= 2 && 88 | value(lines[lines.size()-2]) >= value(lines.back())) { 89 | lines.pop_back(); 90 | } 91 | return value(lines.back()); 92 | } 93 | } 94 | }; 95 | -------------------------------------------------------------------------------- /src/datastructure/dice.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * +x=0 +y=1 +z=2 3 | * d = [+x, +y, +z] 4 | * dir[4] = [+x, +y, -x, -y] 5 | * Dice(a, b): +x=a +y=bとなるサイコロ生成 6 | * get(dir): dir方向の値を取得 7 | * rot(dir): dir方向に転がす 8 | */ 9 | struct Dice { 10 | int d[3]; 11 | Dice(int a, int b) { 12 | for (int i = 0; i < 3; i++) { 13 | d[i] = (a + i) % 3 + a / 3 * 3; 14 | } 15 | while (d[1] != b) rot(1); 16 | } 17 | int get(int dir) { 18 | if (dir < 2) { 19 | return d[dir]; 20 | } else { 21 | dir -= 2; 22 | return 5 - d[dir]; 23 | } 24 | } 25 | void rot(int dir) { 26 | int t = d[2]; 27 | if (dir < 2) { 28 | d[2] = 5 - d[dir]; 29 | d[dir] = t; 30 | } else { 31 | dir -= 2; 32 | d[2] = d[dir]; 33 | d[dir] = 5 - t; 34 | } 35 | } 36 | }; 37 | -------------------------------------------------------------------------------- /src/datastructure/disjointtable.hpp: -------------------------------------------------------------------------------- 1 | template struct DisjointTable { 2 | D e; 3 | OP op; 4 | VV data; 5 | DisjointTable(V v = V(), D _e = D(), OP _op = OP()) : e(_e), op(_op) { 6 | int lg = 1; 7 | while ((1 << lg) < int(v.size())) lg++; 8 | int n = 1 << lg; 9 | v.resize(n, e); 10 | data = VV(lg, V(n)); 11 | data[0] = v; 12 | for (int h = 1; h < lg; h++) { 13 | int u = (1 << h); 14 | for (int i = 0; i < n / (2 * u); i++) { 15 | int base = i * (2 * u) + u; 16 | D res; 17 | res = e; 18 | for (int j = base - 1; j >= base - u; j--) { 19 | res = op(v[j], res); 20 | data[h][j] = res; 21 | } 22 | res = e; 23 | for (int j = base; j < base + u; j++) { 24 | res = op(res, v[j]); 25 | data[h][j] = res; 26 | } 27 | } 28 | } 29 | } 30 | D query(int l, int r) { 31 | r--; 32 | if (l > r) return e; 33 | if (l == r) return data[0][l]; 34 | int u = bsr(uint(l ^ r)); 35 | return op(data[u][l], data[u][r]); 36 | } 37 | }; 38 | 39 | template 40 | DisjointTable get_disjoint_table(V v, D e, OP op) { 41 | return DisjointTable(v, e, op); 42 | } 43 | -------------------------------------------------------------------------------- /src/datastructure/fastset.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "bitop.hpp" 4 | struct FastSet { 5 | static constexpr uint B = 64; 6 | int n, lg; 7 | VV seg; 8 | FastSet(int _n) : n(_n) { 9 | do { 10 | seg.push_back(V((_n + B - 1) / B)); 11 | _n = (_n + B - 1) / B; 12 | } while (_n > 1); 13 | lg = int(seg.size()); 14 | } 15 | bool operator[](int i) const { 16 | return (seg[0][i / B] >> (i % B) & 1) != 0; 17 | } 18 | void set(int i) { 19 | for (int h = 0; h < lg; h++) { 20 | seg[h][i / B] |= 1ULL << (i % B); 21 | i /= B; 22 | } 23 | } 24 | void reset(int i) { 25 | for (int h = 0; h < lg; h++) { 26 | seg[h][i / B] &= ~(1ULL << (i % B)); 27 | if (seg[h][i / B]) break; 28 | i /= B; 29 | } 30 | } 31 | // x以上最小の要素 32 | int next(int i) { 33 | for (int h = 0; h < lg; h++) { 34 | if (i / B == seg[h].size()) break; 35 | ull d = seg[h][i / B] >> (i % B); 36 | if (!d) { 37 | i = i / B + 1; 38 | continue; 39 | } 40 | // find 41 | i += bsf(d); 42 | for (int g = h - 1; g >= 0; g--) { 43 | i *= B; 44 | i += bsf(seg[g][i / B]); 45 | } 46 | return i; 47 | } 48 | return n; 49 | } 50 | // x未満最大の要素 51 | int prev(int i) { 52 | i--; 53 | for (int h = 0; h < lg; h++) { 54 | if (i == -1) break; 55 | ull d = seg[h][i / B] << (63 - i % 64); 56 | if (!d) { 57 | i = i / B - 1; 58 | continue; 59 | } 60 | // find 61 | i += bsr(d) - (B - 1); 62 | for (int g = h - 1; g >= 0; g--) { 63 | i *= B; 64 | i += bsr(seg[g][i / B]); 65 | } 66 | return i; 67 | } 68 | return -1; 69 | } 70 | }; 71 | -------------------------------------------------------------------------------- /src/datastructure/fenwick.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "base.hpp" 4 | 5 | template struct Fenwick { 6 | int n; 7 | V seg; 8 | Fenwick(int _n = 0) : n(_n), seg(n) {} 9 | /// i番目の要素にxを追加する 10 | void add(int i, T x) { 11 | i++; 12 | while (i <= n) { 13 | seg[i - 1] += x; 14 | i += i & -i; 15 | } 16 | } 17 | /// [0, i)のsum 18 | T sum(int i) { 19 | assert(0 <= i && i <= n); 20 | T s = 0; 21 | while (i > 0) { 22 | s += seg[i - 1]; 23 | i -= i & -i; 24 | } 25 | return s; 26 | } 27 | /// [a, b)のsum 28 | T sum(int a, int b) { 29 | assert(0 <= a && a <= b && b <= n); 30 | return sum(b) - sum(a); 31 | } 32 | /// sum[0, idx) >= xなる最小のidx(sum[0, n) < x なら n+1) 33 | int sum_lower_bound(T x) { 34 | if (x <= 0) return 0; 35 | int res = 0, len = 1; 36 | while (2 * len <= n) len *= 2; 37 | for (; len >= 1; len /= 2) { 38 | if (res + len <= n && seg[res + len - 1] < x) { 39 | res += len; 40 | x -= seg[res - 1]; 41 | } 42 | } 43 | return res + 1; 44 | } 45 | }; 46 | -------------------------------------------------------------------------------- /src/datastructure/fenwick2d.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "base.hpp" 4 | #include "datastructure/fenwick.hpp" 5 | 6 | template struct Fenwick2D { 7 | using P = pair; 8 | V

points; 9 | VV ys; 10 | V> fws; 11 | int lg, sz; 12 | Fenwick2D(V

_points) : points(_points) { 13 | sort(points.begin(), points.end()); 14 | points.erase(unique(points.begin(), points.end()), points.end()); 15 | int n = int(points.size()); 16 | lg = 1; 17 | while ((1 << lg) < n) lg++; 18 | sz = 1 << lg; 19 | ys = VV(2 * sz); 20 | for (int i = 0; i < n; i++) ys[sz + i].push_back(points[i].second); 21 | for (int i = sz - 1; i >= 1; i--) { 22 | ys[i] = V(ys[2 * i].size() + ys[2 * i + 1].size()); 23 | merge(ys[2 * i].begin(), ys[2 * i].end(), ys[2 * i + 1].begin(), 24 | ys[2 * i + 1].end(), ys[i].begin()); 25 | } 26 | fws = V>(2 * sz); 27 | for (int i = 1; i < 2 * sz; i++) { 28 | fws[i] = Fenwick(int(ys[i].size())); 29 | } 30 | } 31 | 32 | void add(P p, D x) { 33 | int k = 34 | int(lower_bound(points.begin(), points.end(), p) - points.begin()); 35 | k += sz; 36 | while (k) { 37 | int yid = int(lower_bound(ys[k].begin(), ys[k].end(), p.second) - 38 | ys[k].begin()); 39 | fws[k].add(yid, x); 40 | k >>= 1; 41 | } 42 | } 43 | 44 | D sum(int a, int b, I lw, I up, int l, int r, int k) { 45 | if (b <= l || r <= a) return D(0); 46 | if (a <= l && r <= b) { 47 | int lid = int(lower_bound(ys[k].begin(), ys[k].end(), lw) - 48 | ys[k].begin()); 49 | int uid = int(lower_bound(ys[k].begin(), ys[k].end(), up) - 50 | ys[k].begin()); 51 | return fws[k].sum(lid, uid); 52 | } 53 | int mid = (l + r) / 2; 54 | return sum(a, b, lw, up, l, mid, 2 * k) + 55 | sum(a, b, lw, up, mid, r, 2 * k + 1); 56 | } 57 | 58 | D sum(P lw, P up) { 59 | int a = int(lower_bound(points.begin(), points.end(), lw.first, 60 | [&](P p, I x) { return p.first < x; }) - 61 | points.begin()); 62 | int b = int(lower_bound(points.begin(), points.end(), up.first, 63 | [&](P p, I x) { return p.first < x; }) - 64 | points.begin()); 65 | return sum(a, b, lw.second, up.second, 0, sz, 1); 66 | } 67 | }; 68 | -------------------------------------------------------------------------------- /src/datastructure/hashmap.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "util/hash.hpp" 4 | 5 | template > struct HashMap { 6 | using P = pair; 7 | uint s, mask, filled; // data.size() == 1 << s 8 | P* key; 9 | D* val; 10 | 11 | HashMap(uint _s = 2) : s(_s), mask((1U << s) - 1), filled(0) { 12 | key = new P[1 << s]; 13 | val = new D[1 << s]; 14 | } 15 | 16 | void rehash() { 17 | uint pmask = mask; 18 | P* pkey = key; 19 | D* pval = val; 20 | s++; 21 | mask = (1U << s) - 1; 22 | filled = 0; 23 | key = new P[1 << s]; 24 | val = new D[1 << s]; 25 | for (uint i = 0; i <= pmask; i++) { 26 | if (pkey[i].first == 1) { 27 | set(pkey[i].second, pval[i]); 28 | } 29 | } 30 | delete[] pkey; 31 | delete[] pval; 32 | } 33 | 34 | D get(K k) { 35 | uint id = H::hash(k) & mask; 36 | int gc = 0; 37 | while (key[id].first && key[id].second != k) { 38 | gc++; 39 | id = (id + 1) & mask; 40 | } 41 | if (key[id].first != 1 || key[id].second != k) return D(); 42 | return val[id]; 43 | } 44 | 45 | void set(K k, D x) { 46 | uint id = H::hash(k) & mask; 47 | while (key[id].first && key[id].second != k) id = (id + 1) & mask; 48 | if (key[id].first == 0) { 49 | filled++; 50 | if (filled * 2 > mask) { 51 | rehash(); 52 | set(k, x); 53 | return; 54 | } 55 | } 56 | key[id] = {1, k}; 57 | val[id] = x; 58 | } 59 | 60 | bool remove(K k) { 61 | uint id = H::hash(k) & mask; 62 | while (key[id].first && key[id].second != k) id = (id + 1) & mask; 63 | if (key[id].first != 1) return false; 64 | key[id].first = 2; 65 | return true; 66 | } 67 | }; 68 | -------------------------------------------------------------------------------- /src/datastructure/hashset.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "util/hash.hpp" 4 | 5 | template > struct HashSet { 6 | using P = pair; 7 | uint s, mask, filled, sz; // data.size() == 1 << s 8 | P* key; 9 | 10 | HashSet(uint _s = 2) : s(_s), mask((1U << s) - 1), filled(0), sz(0) { 11 | key = new P[1 << s]; 12 | } 13 | 14 | void rehash() { 15 | uint pmask = mask; 16 | P* pkey = key; 17 | s++; 18 | mask = (1U << s) - 1; 19 | filled = 0; 20 | sz = 0; 21 | key = new P[1 << s]; 22 | for (uint i = 0; i <= pmask; i++) { 23 | if (pkey[i].first == 1) { 24 | insert(pkey[i].second); 25 | } 26 | } 27 | delete[] pkey; 28 | } 29 | 30 | bool count(K k) { 31 | uint id = H::hash(k) & mask; 32 | int gc = 0; 33 | while (key[id].first && key[id].second != k) { 34 | gc++; 35 | id = (id + 1) & mask; 36 | } 37 | if (key[id].first != 1 || key[id].second != k) return false; 38 | return true; 39 | } 40 | 41 | void insert(K k) { 42 | uint id = H::hash(k) & mask; 43 | while (key[id].first && key[id].second != k) id = (id + 1) & mask; 44 | if (key[id].first == 0) { 45 | filled++; 46 | if (filled * 2 > mask) { 47 | rehash(); 48 | insert(k); 49 | return; 50 | } 51 | } 52 | if (key[id].first != 1) sz++; 53 | key[id] = {1, k}; 54 | } 55 | 56 | bool erase(K k) { 57 | uint id = H::hash(k) & mask; 58 | while (key[id].first && key[id].second != k) id = (id + 1) & mask; 59 | if (key[id].first != 1) return false; 60 | sz--; 61 | key[id].first = 2; 62 | return true; 63 | } 64 | 65 | size_t size() const { 66 | return sz; 67 | } 68 | 69 | V to_vec() const { 70 | V result; 71 | for (uint i = 0; i <= mask; i++) { 72 | if (key[i].first == 1) { 73 | result.push_back(key[i].second); 74 | } 75 | } 76 | return result; 77 | } 78 | }; 79 | -------------------------------------------------------------------------------- /src/datastructure/linkcuttree.hpp: -------------------------------------------------------------------------------- 1 | template struct LCNode { 2 | using NP = LCNode*; 3 | using D = typename N::D; 4 | NP p = nullptr, l = nullptr, r = nullptr; 5 | int sz = 1; 6 | bool rev = false; 7 | D v = N::e_d(), sm = N::e_d(); 8 | 9 | void single_set(D x) { 10 | v = x; 11 | update(); 12 | } 13 | void single_add(D x) { 14 | v = N::op_dd(v, x); 15 | update(); 16 | } 17 | 18 | void init_node(D _v) { 19 | v = _v; 20 | sm = _v; 21 | } 22 | void update() { 23 | sz = 1; 24 | if (l) sz += l->sz; 25 | if (r) sz += r->sz; 26 | sm = l ? N::op_dd(l->sm, v) : v; 27 | if (r) sm = N::op_dd(sm, r->sm); 28 | } 29 | void push() { 30 | if (rev) { 31 | if (l) l->revdata(); 32 | if (r) r->revdata(); 33 | rev = false; 34 | } 35 | } 36 | void revdata() { 37 | rev ^= true; 38 | swap(l, r); 39 | sm = N::rev(sm); 40 | } 41 | 42 | inline int pos() { 43 | if (p) { 44 | if (p->l == this) return -1; 45 | if (p->r == this) return 1; 46 | } 47 | return 0; 48 | } 49 | void rot() { 50 | NP q = p->p; 51 | int pps = p->pos(); 52 | if (pps == -1) q->l = this; 53 | if (pps == 1) q->r = this; 54 | if (p->l == this) { 55 | p->l = r; 56 | if (r) r->p = p; 57 | r = p; 58 | } else { 59 | p->r = l; 60 | if (l) l->p = p; 61 | l = p; 62 | } 63 | p->p = this; 64 | p->update(); 65 | update(); 66 | p = q; 67 | if (q) q->update(); 68 | } 69 | void all_push() { 70 | if (pos()) p->all_push(); 71 | push(); 72 | } 73 | void splay() { 74 | all_push(); 75 | int ps; 76 | while ((ps = pos())) { 77 | int pps = p->pos(); 78 | if (!pps) { 79 | rot(); 80 | } else if (ps == pps) { 81 | p->rot(); 82 | rot(); 83 | } else { 84 | rot(); 85 | rot(); 86 | } 87 | } 88 | } 89 | void expose() { 90 | NP u = this, ur = nullptr; 91 | do { 92 | u->splay(); 93 | u->r = ur; 94 | u->update(); 95 | ur = u; 96 | } while ((u = u->p)); 97 | splay(); 98 | } 99 | // 親としてnpを接続する 100 | void link(NP np) { 101 | evert(); 102 | np->expose(); 103 | p = np; 104 | } 105 | // 親から自分を切り離す 106 | void cut() { 107 | expose(); 108 | assert(l); 109 | l->p = nullptr; 110 | l = nullptr; 111 | update(); 112 | } 113 | void evert() { 114 | expose(); 115 | revdata(); 116 | } 117 | 118 | NP lca(NP n) { 119 | n->expose(); 120 | expose(); 121 | NP t = n; 122 | while (n->p != nullptr) { 123 | if (!n->pos()) t = n->p; 124 | n = n->p; 125 | } 126 | return (this == n) ? t : nullptr; 127 | } 128 | }; 129 | -------------------------------------------------------------------------------- /src/datastructure/linkcuttree_old.hpp: -------------------------------------------------------------------------------- 1 | struct LCNode { 2 | using NP = LCNode*; 3 | static NP last; 4 | ll d, dsm, ma; 5 | ll lz; 6 | NP init_last() { 7 | sz = 0; // Important 8 | lz = 0; // Important 9 | d = dsm = ma = 0; 10 | return this; 11 | } 12 | void init_node(int d) { 13 | sz = 1; rev = false; // Important 14 | lz = 0; // Important 15 | this->d = dsm = ma = d; 16 | } 17 | void update() { 18 | sz = 1 + l->sz + r->sz; // Important 19 | dsm = d + l->dsm + r->dsm; 20 | ma = max(d, max(l->ma, r->ma)); 21 | } 22 | void push() { 23 | assert(this != last); 24 | if (rev) { // Important 25 | if (l != last) { 26 | l->revdata(); 27 | } 28 | if (r != last) { 29 | r->revdata(); 30 | } 31 | rev = false; 32 | } 33 | if (lz) { 34 | if (l != last) { 35 | l->lzdata(lz); 36 | } 37 | if (r != last) { 38 | r->lzdata(lz); 39 | } 40 | lz = 0; 41 | } 42 | } 43 | void revdata() { 44 | rev ^= true; swap(l, r); // Important 45 | } 46 | void lzdata(ll x) { 47 | d += x; 48 | dsm += x; 49 | ma += x; 50 | lz += x; 51 | } 52 | 53 | NP p, l, r; 54 | int sz; 55 | bool rev; 56 | LCNode() : p(nullptr), l(last), r(last) {} 57 | inline int pos() { 58 | if (p) { 59 | if (p->l == this) return -1; 60 | if (p->r == this) return 1; 61 | } 62 | return 0; 63 | } 64 | void rot() { 65 | NP q = p->p; 66 | int pps = p->pos(); 67 | if (pps == -1) q->l = this; 68 | if (pps == 1) q->r = this; 69 | if (p->l == this) { 70 | p->l = r; 71 | if (r) r->p = p; 72 | r = p; 73 | } else { 74 | p->r = l; 75 | if (l) l->p = p; 76 | l = p; 77 | } 78 | p->p = this; 79 | p->update(); update(); 80 | p = q; 81 | if (q) q->update(); 82 | } 83 | void splay() { 84 | supush(); 85 | int ps; 86 | while ((ps = pos())) { 87 | int pps = p->pos(); 88 | if (!pps) { 89 | rot(); 90 | } else if (ps == pps) { 91 | p->rot(); rot(); 92 | } else { 93 | rot(); rot(); 94 | } 95 | } 96 | } 97 | void expose() { 98 | assert(this != last); 99 | NP u = this, ur = last; 100 | do { 101 | u->splay(); 102 | u->r = ur; 103 | u->update(); 104 | ur = u; 105 | } while ((u = u->p)); 106 | splay(); 107 | } 108 | void supush() { 109 | if (pos()) p->supush(); 110 | push(); 111 | } 112 | void link(NP r) { 113 | evert(); r->expose(); 114 | p = r; 115 | } 116 | void cut() { 117 | expose(); 118 | l->p = NULL; 119 | l = last; 120 | update(); 121 | } 122 | void evert() { 123 | expose(); revdata(); 124 | } 125 | 126 | //tree func 127 | NP parent() { 128 | expose(); 129 | NP u = this->l; 130 | if (u == last) return last; 131 | u->push(); 132 | while (u->r != last) { 133 | u = u->r; 134 | u->push(); 135 | } 136 | u->expose(); 137 | return u; 138 | } 139 | 140 | NP root() { 141 | expose(); 142 | NP u = this; 143 | while (u->l != last) { 144 | u = u->l; 145 | u->push(); 146 | } 147 | u->expose(); 148 | return u; 149 | } 150 | 151 | 152 | NP lca(NP n) { 153 | n->expose(); 154 | expose(); 155 | NP t = n; 156 | while (n->p != nullptr) { 157 | if (!n->pos()) t = n->p; 158 | n = n->p; 159 | } 160 | return (this == n) ? t : nullptr; 161 | } 162 | }; 163 | LCNode::NP LCNode::last = (new LCNode())->init_last(); 164 | -------------------------------------------------------------------------------- /src/datastructure/quickfind.hpp: -------------------------------------------------------------------------------- 1 | struct QuickFind { 2 | V id; 3 | VV groups; 4 | int gc; // group count 5 | QuickFind(int n = 0) { 6 | id = V(n); 7 | groups = VV(n); 8 | for (int i = 0; i < n; i++) { 9 | id[i] = i; 10 | groups[i] = {i}; 11 | } 12 | gc = n; 13 | } 14 | void merge(int a, int b) { 15 | if (same(a, b)) return; 16 | gc--; 17 | int x = id[a], y = id[b]; 18 | if (groups[x].size() < groups[y].size()) swap(x, y); 19 | for (int j : groups[y]) { 20 | id[j] = x; 21 | groups[x].push_back(j); 22 | } 23 | groups[y].clear(); 24 | } 25 | bool same(int a, int b) { return id[a] == id[b]; } 26 | }; 27 | -------------------------------------------------------------------------------- /src/datastructure/radixheap.hpp: -------------------------------------------------------------------------------- 1 | // D.key must be unsigned integer 2 | template struct RadixHeap { 3 | using C = typename make_unsigned::type; 4 | static int bsr1(C x) { return (x == 0) ? 0 : bsr(x) + 1; } 5 | size_t sz = 0, cnt = 0; 6 | C last = 0; 7 | VV v = VV(sizeof(C) * 8 + 1); 8 | RadixHeap() {} 9 | void push(D x) { 10 | assert(decltype(x.key)(last) <= x.key); 11 | sz++; 12 | v[bsr1(x.key ^ last)].push_back(x); 13 | } 14 | void pull() { 15 | if (cnt < v[0].size()) return; 16 | int i = 1; 17 | while (v[i].empty()) i++; 18 | last = min_element(v[i].begin(), v[i].end(), [&](D l, D r) { 19 | return l.key < r.key; 20 | })->key; 21 | for (D x : v[i]) { 22 | v[bsr1(x.key ^ last)].push_back(x); 23 | } 24 | v[i].clear(); 25 | } 26 | D top() { 27 | pull(); 28 | return v[0][cnt]; 29 | } 30 | void pop() { 31 | pull(); 32 | sz--; 33 | cnt++; 34 | } 35 | size_t size() const { return sz; } 36 | bool empty() const { return sz == 0; } 37 | }; 38 | -------------------------------------------------------------------------------- /src/datastructure/simplequeue.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | template struct SimpleQueue { 4 | V payload; 5 | size_t pos = 0; 6 | void reserve(size_t size) { payload.reserve(size); } 7 | size_t size() const { return payload.size() - pos; } 8 | bool empty() const { return pos == payload.size(); } 9 | void push(const T& t) { payload.push_back(t); } 10 | T& front() { 11 | assert(!empty()); 12 | return payload[pos]; 13 | } 14 | void clear() { 15 | payload.clear(); 16 | pos = 0; 17 | } 18 | void pop() { 19 | assert(!empty()); 20 | pos++; 21 | } 22 | }; 23 | -------------------------------------------------------------------------------- /src/datastructure/smallfind.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | template struct SmallFind { 4 | array id; 5 | SmallFind() { 6 | for (int i = 0; i < N; i++) id[i] = i; 7 | } 8 | 9 | SmallFind(ull hs) { 10 | for (int i = 0; i < N; i++) { 11 | id[i] = hs & 0xf; 12 | hs >>= 4; 13 | } 14 | } 15 | 16 | void merge(int x, int y) { 17 | int xg = id[x], yg = id[y]; 18 | if (xg == yg) return; 19 | for (int i = 0; i < N; i++) { 20 | if (id[i] == yg) id[i] = xg; 21 | } 22 | } 23 | 24 | bool same(int x, int y) { return id[x] == id[y]; } 25 | 26 | ull uf2hash() { 27 | array b; 28 | fill(b.begin(), b.end(), -1); 29 | int c = 0; 30 | ull hs = 0; 31 | for (int i = N - 1; i >= 0; i--) { 32 | hs <<= 4; 33 | if (b[id[i]] == -1) { 34 | b[id[i]] = c++; 35 | } 36 | hs += b[id[i]]; 37 | } 38 | return hs; 39 | } 40 | }; 41 | -------------------------------------------------------------------------------- /src/datastructure/sort_mo.hpp: -------------------------------------------------------------------------------- 1 | // 普通にsortした方が早くない?困ったね 2 | template void sort_mo(V& ques) { 3 | auto dist = [&](Q x, Q y) { return abs(x.l - y.l) + abs(x.r - y.r); }; 4 | int n = int(ques.size()); 5 | if (n <= 1) return; 6 | 7 | // ordered by manhattan mst (tsp approx) 8 | { 9 | VV tr(n); 10 | V> ps(n); 11 | for (int i = 0; i < n; i++) { 12 | ps[i] = {ques[i].l, ques[i].r}; 13 | } 14 | auto edges = manhattan_mst(ps); 15 | for (auto e : edges) { 16 | tr[e.first].push_back(e.second); 17 | tr[e.second].push_back(e.first); 18 | } 19 | V nques; 20 | auto dfs = [&](auto self, int p, int b) -> void { 21 | nques.push_back(ques[p]); 22 | for (auto d : tr[p]) { 23 | if (d == b) continue; 24 | self(self, d, p); 25 | } 26 | }; 27 | dfs(dfs, 0, -1); 28 | ques = nques; 29 | } 30 | // 2-opt 31 | for (int ph = 0; ph < 10; ph++) { 32 | for (int i = 1; i < n; i++) { 33 | for (int j = i + 1; j < min(i + 10, n - 1); j++) { 34 | ll pre = 35 | dist(ques[i - 1], ques[i]) + dist(ques[j], ques[j + 1]); 36 | ll now = 37 | dist(ques[i - 1], ques[j]) + dist(ques[i], ques[j + 1]); 38 | if (now < pre) { 39 | reverse(ques.begin() + i, ques.begin() + j + 1); 40 | } 41 | } 42 | } 43 | } 44 | // reverse first 45 | { 46 | int mi = TEN(9), idx = -1; 47 | for (int i = 0; i < n - 1; i++) { 48 | int nw = abs(ques[i].l - ques[i].r) + dist(ques[0], ques[i + 1]); 49 | if (nw < mi) { 50 | mi = nw; 51 | idx = i; 52 | } 53 | } 54 | reverse(ques.begin(), ques.begin() + idx + 1); 55 | } 56 | // reverse last 57 | { 58 | int mi = TEN(9), idx = -1; 59 | for (int i = 1; i < n; i++) { 60 | int nw = dist(ques[i - 1], ques[n - 1]); 61 | if (nw < mi) { 62 | mi = nw; 63 | idx = i; 64 | } 65 | } 66 | reverse(ques.begin() + idx, ques.end()); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/datastructure/sparsetable.hpp: -------------------------------------------------------------------------------- 1 | template struct SparseTable { 2 | D e; 3 | OP op; 4 | VV data; 5 | SparseTable(V v = V(), D _e = D(), OP _op = OP()) : e(_e), op(_op) { 6 | int n = int(v.size()); 7 | if (n == 0) return; 8 | int lg = bsr(uint(n)) + 1; 9 | data = VV(lg); 10 | data[0] = v; 11 | int l = 1; 12 | for (int s = 1; s < lg; s++) { 13 | data[s] = V(n); 14 | for (int i = 0; i < n - l; i++) { 15 | data[s][i] = op(data[s - 1][i], data[s - 1][i + l]); 16 | } 17 | l <<= 1; 18 | } 19 | } 20 | D query(int l, int r) const { 21 | assert(l <= r); 22 | if (l == r) return e; 23 | int u = bsr(uint(r - l)); 24 | return op(data[u][l], data[u][r - (1 << u)]); 25 | } 26 | }; 27 | template 28 | SparseTable get_sparse_table(V v, D e, OP op) { 29 | return SparseTable(v, e, op); 30 | } 31 | 32 | template struct LowMemorySparseTable { 33 | static constexpr int B = 16; 34 | V data; 35 | D e; 36 | OP op; 37 | SparseTable st; 38 | V comp_arr(V v) { 39 | int n = int(v.size()); 40 | V comp(n / B); 41 | for (int i = 0; i < n / B; i++) { 42 | D res = data[i * B]; 43 | for (int j = 1; j < B; j++) { 44 | res = op(res, data[i * B + j]); 45 | } 46 | comp[i] = res; 47 | } 48 | return comp; 49 | } 50 | LowMemorySparseTable(V v = V(), D _e = D(), OP _op = OP()) 51 | : data(v), e(_e), op(_op), st(comp_arr(v), _e, _op) {} 52 | D query(int l, int r) const { 53 | assert(l <= r); 54 | if (l == r) return e; 55 | int lb = (l + B - 1) / B, rb = r / B; 56 | D res = e; 57 | if (lb >= rb) { 58 | for (int i = l; i < r; i++) { 59 | res = op(res, data[i]); 60 | } 61 | return res; 62 | } 63 | 64 | while (l % B) { 65 | res = op(res, data[l]); 66 | l++; 67 | } 68 | while (r % B) { 69 | r--; 70 | res = op(res, data[r]); 71 | } 72 | res = op(res, st.query(lb, rb)); 73 | return res; 74 | } 75 | }; 76 | template 77 | LowMemorySparseTable get_low_memory_sparse_table(V v, D e, OP op) { 78 | return LowMemorySparseTable(v, e, op); 79 | } 80 | -------------------------------------------------------------------------------- /src/datastructure/staticrangesum.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "base.hpp" 4 | 5 | template struct StaticRangeSum { 6 | struct P { 7 | I x, y; 8 | D val; 9 | }; 10 | 11 | StaticRangeSum(V

ps) { 12 | if (!ps.size()) return; 13 | sort(ps.begin(), ps.end(), [&](P l, P r) { return l.x < r.x; }); 14 | for (auto p : ps) { 15 | xs.push_back(p.x); 16 | ys.push_back(p.y); 17 | } 18 | sort(ys.begin(), ys.end()); 19 | ys.erase(unique(ys.begin(), ys.end()), ys.end()); 20 | 21 | int n = int(xs.size()); 22 | int m = int(ys.size()); 23 | 24 | lg = 1; 25 | while ((1 << lg) < m) lg++; 26 | 27 | mid = V(lg); 28 | bits = VV(lg, V(n + 1)); 29 | sums = VV(lg + 1, V(n + 1)); 30 | 31 | struct Q { 32 | int y; 33 | D val; 34 | }; 35 | V v; 36 | for (auto p : ps) { 37 | int y = int(lower_bound(ys.begin(), ys.end(), p.y) - ys.begin()); 38 | v.push_back({y, p.val}); 39 | } 40 | for (int i = 0; i < n; i++) { 41 | Q q = v[i]; 42 | sums[lg][i + 1] = sums[lg][i] + q.val; 43 | } 44 | for (int lv = lg - 1; lv >= 0; lv--) { 45 | array, 2> nx; 46 | for (int i = 0; i < n; i++) { 47 | Q q = v[i]; 48 | bool f = (q.y >> lv) & 1; 49 | bits[lv][i + 1] = bits[lv][i] + (f ? 0 : 1); 50 | nx[f].push_back(q); 51 | } 52 | mid[lv] = int(nx[0].size()); 53 | v.clear(); 54 | v.insert(v.end(), nx[0].begin(), nx[0].end()); 55 | v.insert(v.end(), nx[1].begin(), nx[1].end()); 56 | for (int i = 0; i < n; i++) { 57 | Q q = v[i]; 58 | sums[lv][i + 1] = sums[lv][i] + q.val; 59 | } 60 | } 61 | } 62 | // (low_x <= x < up_x), (low_y <= y < up_y)なる点の重みの総和 63 | D sum(I low_x, I low_y, I up_x, I up_y) { 64 | int _lx = int(lower_bound(xs.begin(), xs.end(), low_x) - xs.begin()); 65 | int _ux = int(lower_bound(xs.begin(), xs.end(), up_x) - xs.begin()); 66 | int _ly = int(lower_bound(ys.begin(), ys.end(), low_y) - ys.begin()); 67 | int _uy = int(lower_bound(ys.begin(), ys.end(), up_y) - ys.begin()); 68 | if (_lx >= _ux || _ly >= _uy) return D(0); 69 | return sum(_lx, _ux, _uy) - sum(_lx, _ux, _ly); 70 | } 71 | 72 | private: 73 | int lg; 74 | V xs, ys; 75 | 76 | V mid; 77 | VV bits; 78 | VV sums; 79 | D sum(int l, int r, int u) { 80 | if (u == (1 << lg)) return sums[lg][r] - sums[lg][l]; 81 | D ans = 0; 82 | for (int lv = lg - 1; lv >= 0; lv--) { 83 | bool f = (u >> lv) & 1; 84 | int l0 = bits[lv][l], r0 = bits[lv][r]; 85 | if (f) { 86 | ans += sums[lv][r0] - sums[lv][l0]; 87 | l = l - l0 + mid[lv]; 88 | r = r - r0 + mid[lv]; 89 | } else { 90 | l = l0; 91 | r = r0; 92 | } 93 | } 94 | return ans; 95 | } 96 | }; 97 | -------------------------------------------------------------------------------- /src/datastructure/staticrangeunion.hpp: -------------------------------------------------------------------------------- 1 | struct StaticRangeUnion { 2 | using P = pair; 3 | int n; 4 | VV

ques; 5 | StaticRangeUnion(int _n = 0) : n(_n), ques(n + 1) {} 6 | void merge(int a, int b, int di) { 7 | if (di == 0) return; 8 | ques[min(di, n)].push_back({a, b}); 9 | } 10 | UnionFind exec() { 11 | UnionFind uf(n); 12 | V

que; 13 | for (int di = n; di >= 1; di--) { 14 | for (auto p : ques[di]) que.push_back(p); 15 | V

nque; 16 | for (auto p : que) { 17 | if (uf.same(p.first, p.second)) continue; 18 | uf.merge(p.first, p.second); 19 | nque.push_back({p.first + 1, p.second + 1}); 20 | } 21 | que = nque; 22 | } 23 | return uf; 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /src/datastructure/unionfind.hpp: -------------------------------------------------------------------------------- 1 | struct UnionFind { 2 | int n; 3 | V p, r; 4 | int gn; 5 | UnionFind(int _n = 0) : n(_n), p(n, -1), r(n, 1), gn(n) {} 6 | void merge(int a, int b) { 7 | assert(0 <= a && a < n); 8 | assert(0 <= b && b < n); 9 | int x = group(a), y = group(b); 10 | if (x == y) return; // same 11 | gn--; 12 | if (r[x] < r[y]) swap(x, y); 13 | p[y] = x; 14 | r[x] += r[y]; 15 | } 16 | int group(int a) { 17 | assert(0 <= a && a < n); 18 | if (p[a] == -1) return a; 19 | return p[a] = group(p[a]); 20 | } 21 | bool same(int a, int b) { 22 | assert(0 <= a && a < n); 23 | assert(0 <= b && b < n); 24 | return group(a) == group(b); 25 | } 26 | }; 27 | -------------------------------------------------------------------------------- /src/datastructure/wavelet.hpp: -------------------------------------------------------------------------------- 1 | // wavelet matrix 2 | struct Wavelet { 3 | // space: 32N bits 4 | struct BitVector { 5 | V _rank = {0}; 6 | BitVector(V v = V()) { 7 | _rank.reserve(v.size() + 1); 8 | for (int d : v) _rank.push_back(_rank.back() + d); 9 | } 10 | int rank(bool f, int k) { return f ? _rank[k] : (k - _rank[k]); } 11 | int rank(bool f, int l, int r) { return rank(f, r) - rank(f, l); } 12 | }; 13 | // space: 1.5N bits 14 | /*struct BitVector { 15 | V v; 16 | V _rank; 17 | BitVector(V _v = V()) { 18 | int n = int(_v.size()); 19 | v = V((n + 63) / 64); 20 | _rank = V(v.size() + 1); 21 | for (int i = 0; i < n; i++) { 22 | if (_v[i]) { 23 | v[i / 64] |= 1ULL << (i % 64); 24 | _rank[i / 64 + 1]++; 25 | } 26 | } 27 | for (int i = 0; i < int(v.size()); i++) { 28 | _rank[i+1] += _rank[i]; 29 | } 30 | } 31 | int rank(int k) { 32 | int a = _rank[k / 64]; 33 | if (k % 64) a += __builtin_popcountll(v[k / 64] << (64 - k % 64)); 34 | return a; 35 | } 36 | int rank(bool f, int k) { return f ? rank(k) : k - rank(k); } 37 | int rank(bool f, int l, int r) { return rank(f, r) - rank(f, l); } 38 | };*/ 39 | 40 | int n, lg = 1; 41 | V mid; 42 | V data; 43 | Wavelet(V v = V()) : n(int(v.size())) { 44 | int ma = 0; 45 | for (int x : v) ma = max(ma, x); 46 | while ((1 << lg) <= ma) lg++; 47 | mid = V(lg); 48 | data = V(lg); 49 | for (int lv = lg - 1; lv >= 0; lv--) { 50 | V buf; 51 | VV nx(2); 52 | for (int d : v) { 53 | bool f = (d & (1 << lv)) > 0; 54 | buf.push_back(f); 55 | nx[f].push_back(d); 56 | } 57 | mid[lv] = int(nx[0].size()); 58 | data[lv] = BitVector(buf); 59 | v.clear(); 60 | v.insert(v.end(), nx[0].begin(), nx[0].end()); 61 | v.insert(v.end(), nx[1].begin(), nx[1].end()); 62 | } 63 | } 64 | pair succ(bool f, int a, int b, int lv) { 65 | int na = data[lv].rank(f, a) + (f ? mid[lv] : 0); 66 | int nb = data[lv].rank(f, b) + (f ? mid[lv] : 0); 67 | return make_pair(na, nb); 68 | } 69 | // count i, s.t. (a <= i < b) && (v[i] < u) 70 | int rank(int a, int b, int u) { 71 | if ((1 << lg) <= u) return b - a; 72 | int ans = 0; 73 | for (int lv = lg - 1; lv >= 0; lv--) { 74 | bool f = (u & (1 << lv)) > 0; 75 | if (f) ans += data[lv].rank(false, a, b); 76 | tie(a, b) = succ(f, a, b, lv); 77 | } 78 | return ans; 79 | } 80 | // k-th(0-indexed!) number in v[a..b] 81 | int select(int a, int b, int k) { 82 | int u = 0; 83 | for (int lv = lg - 1; lv >= 0; lv--) { 84 | int le = data[lv].rank(false, a, b); 85 | bool f = (le <= k); 86 | if (f) { 87 | u += (1 << lv); 88 | k -= le; 89 | } 90 | tie(a, b) = succ(f, a, b, lv); 91 | } 92 | return u; 93 | } 94 | }; 95 | 96 | struct CompressWavelet { 97 | Wavelet wt; 98 | V v, vidx; 99 | int zip(int x) { 100 | return int(lower_bound(vidx.begin(), vidx.end(), x) - vidx.begin()); 101 | } 102 | CompressWavelet(V _v = V()) : v(_v), vidx(v) { 103 | sort(vidx.begin(), vidx.end()); 104 | vidx.erase(unique(vidx.begin(), vidx.end()), vidx.end()); 105 | for (auto& d : v) d = zip(d); 106 | wt = Wavelet(v); 107 | } 108 | int rank(int a, int b, int u) { return wt.rank(a, b, zip(u)); } 109 | int select(int a, int b, int k) { return vidx[wt.select(a, b, k)]; } 110 | }; 111 | -------------------------------------------------------------------------------- /src/geo/3d.hpp: -------------------------------------------------------------------------------- 1 | struct Pt3 { 2 | D x, y, z; 3 | Pt3() {} 4 | Pt3(D _x, D _y, D _z) : x(_x), y(_y), z(_z) {} 5 | Pt3 operator+(const Pt3& r) const { return Pt3(x+r.x, y+r.y, z+r.z); } 6 | Pt3 operator-(const Pt3& r) const { return Pt3(x-r.x, y-r.y, z-r.z); } 7 | Pt3& operator-=(const Pt3& r) { return *this = *this - r; } 8 | Pt3 operator-() const { return Pt3(-x, -y, -z); } 9 | 10 | D abs() const { return sqrt(x * x + y * y + z * z); } 11 | D rabs() const { return max({std::abs(x), std::abs(y), std::abs(z)}); } 12 | }; 13 | 14 | struct L3 { 15 | Pt3 s, t; 16 | L3() {} 17 | L3(Pt3 s, Pt3 t) : s(s), t(t) {} 18 | Pt3 vec() const { return t - s; } 19 | D abs() const { return vec().abs(); } 20 | }; 21 | 22 | /* 23 | cng viewpoint 24 | l.sを(0, 0, 0), l.tを(0, 0, l.abs()), pを(0, y>0, z)へ移したときのqの座標を返す 25 | */ 26 | Pt3 cng_vp(L3 l, Pt3 p, Pt3 q) { 27 | l.t -= l.s; p -= l.s; q -= l.s; 28 | 29 | Pt2 base; 30 | base = Pt2::polar(1, PI / 2 - Pt2(l.t.x, l.t.y).arg()); 31 | tie(l.t.x, l.t.y) = (Pt2(l.t.x, l.t.y) * base).to_pair(); 32 | tie(p.x, p.y) = (Pt2(p.x, p.y) * base).to_pair(); 33 | tie(q.x, q.y) = (Pt2(q.x, q.y) * base).to_pair(); 34 | 35 | base = Pt2::polar(1, PI / 2 - Pt2(l.t.y, l.t.z).arg()); 36 | tie(l.t.y, l.t.z) = (Pt2(l.t.y, l.t.z) * base).to_pair(); 37 | tie(p.y, p.z) = (Pt2(p.y, p.z) * base).to_pair(); 38 | tie(q.y, q.z) = (Pt2(q.y, q.z) * base).to_pair(); 39 | 40 | base = Pt2::polar(1, PI / 2 - Pt2(p.x, p.y).arg()); 41 | tie(p.x, p.y) = (Pt2(p.x, p.y) * base).to_pair(); 42 | tie(q.x, q.y) = (Pt2(q.x, q.y) * base).to_pair(); 43 | 44 | return q; 45 | } 46 | -------------------------------------------------------------------------------- /src/geo/delaunay.hpp: -------------------------------------------------------------------------------- 1 | 2 | // 今pが一直線上の時は絶対に使わないで下さい 3 | // 挙動がヤバすぎて,ほぼ100%その場でバグってしまいます。 4 | VV delaunay(const V

& p) { 5 | int n = int(p.size()); 6 | assert(n > 1); 7 | VV mp(n + 2, V(n + 2, -1)); 8 | int special = 0; 9 | for (int i = 1; i < n; i++) 10 | if (p[i] < p[special]) special = i; 11 | using Pi = pair; 12 | stack st; 13 | auto set_tr = [&](int i, int j, int k) { 14 | mp[i][j] = k; 15 | mp[j][k] = i; 16 | mp[k][i] = j; 17 | st.push(Pi(i, j)); 18 | }; 19 | set_tr(special, n, n + 1); 20 | st.pop(); 21 | for (int l = 0; l < n; l++) { 22 | if (l == special) continue; 23 | int i = n, j = n + 1, k = mp[i][j]; 24 | do { 25 | assert(k != -1); 26 | auto succ = [&](int x, int y) { 27 | assert(!(x == n && y == n + 1)); 28 | assert(!(x == n + 1 && y == n)); 29 | if (x == n || y == n + 1) return p[l] < p[min(x, y)]; 30 | if (x == n + 1 || y == n) return p[min(x, y)] < p[l]; 31 | return ccw(p[x], p[y], p[l]) == 1; 32 | }; 33 | if (succ(i, k)) 34 | j = k; 35 | else if (succ(k, j)) 36 | i = k; 37 | else 38 | break; 39 | k = mp[i][j]; 40 | } while (true); 41 | auto on_line = [&](int x, int y, int z) { 42 | if (max(x, y) >= n || ccw(p[x], p[y], p[l]) == 1) return false; 43 | int w = mp[y][x]; 44 | mp[x][y] = mp[y][x] = -1; 45 | set_tr(x, w, l); 46 | set_tr(w, y, l); 47 | set_tr(y, z, l); 48 | set_tr(z, x, l); 49 | return true; 50 | }; 51 | if (!on_line(i, j, k) && !on_line(j, k, i) && !on_line(k, i, j)) { 52 | set_tr(i, j, l); 53 | set_tr(j, k, l); 54 | set_tr(k, i, l); 55 | } 56 | while (st.empty() == false) { 57 | int u, v; 58 | tie(u, v) = st.top(); 59 | st.pop(); 60 | int w = mp[u][v], x = mp[v][u]; 61 | assert(w == l); 62 | if (w < 0 || x < 0 || max(w, x) >= n) continue; 63 | if (max(u, v) < n) { 64 | P a = p[u] - p[x], b = p[v] - p[x], c = p[w] - p[x]; 65 | D z = 0; 66 | z += a.norm() * crs(b, c); 67 | z += b.norm() * crs(c, a); 68 | z += c.norm() * crs(a, b); 69 | if (z <= 0) continue; 70 | } else { 71 | if (u < n && ccw(p[x], p[w], p[u]) != 1) continue; 72 | if (v < n && ccw(p[w], p[x], p[v]) != 1) continue; 73 | } 74 | mp[u][v] = mp[v][u] = -1; 75 | set_tr(u, x, l); 76 | set_tr(x, v, l); 77 | } 78 | } 79 | 80 | set_tr(special, n + 1, n); // for traverse 81 | VV g(n); 82 | for (int i = 0; i < n; i++) { 83 | int s = 0; 84 | for (int j = 0; j < n; j++) { 85 | if (mp[s][i] < mp[j][i]) s = j; 86 | } 87 | int j = s; 88 | bool unbounded = false; 89 | do { 90 | if (j < n) 91 | g[i].push_back(j); 92 | else 93 | unbounded = true; 94 | j = mp[i][j]; 95 | } while (j != s); 96 | if (unbounded) g[i].push_back(n); 97 | } 98 | return g; 99 | } 100 | -------------------------------------------------------------------------------- /src/geo/intersect.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * 幾何(衝突判定) 3 | */ 4 | 5 | P project(const L& l, const P& p) { 6 | P v = l.vec(); 7 | return l.s + v * dot(v, p - l.s) / v.norm(); 8 | } 9 | 10 | bool insSL(const L& s, const L& l) { 11 | int a = ccw(l, s.s), b = ccw(l, s.t); 12 | return (a % 2 == 0 || b % 2 == 0 || a != b); 13 | } 14 | 15 | bool insSS(const L& s, const L& t) { 16 | int a = ccw(s, t.s), b = ccw(s, t.t); 17 | int c = ccw(t, s.s), d = ccw(t, s.t); 18 | if (a * b <= 0 && c * d <= 0) return true; 19 | return false; 20 | } 21 | 22 | D distLP(const L& l, const P& p) { 23 | return abs(crs(l.vec(), p - l.s)) / l.abs(); 24 | } 25 | 26 | D distSP(const L& s, const P& p) { 27 | P q = project(s, p); 28 | if (ccw(s, q) == 0) 29 | return (p - q).abs(); 30 | else 31 | return min((s.s - p).abs(), (s.t - p).abs()); 32 | } 33 | 34 | D distSS(const L& s, const L& t) { 35 | if (insSS(s, t)) return 0; 36 | return min( 37 | {distSP(s, t.s), distSP(s, t.t), distSP(t, s.s), distSP(t, s.t)}); 38 | } 39 | 40 | int crossLL(const L& l, const L& m, P& r) { 41 | D cr1 = crs(l.vec(), m.vec()), cr2 = crs(l.vec(), l.t - m.s); 42 | if (sgncrs(l.vec(), m.vec()) == 0) { 43 | r = l.s; 44 | if (sgncrs(l.vec(), l.t - m.s)) return 0; 45 | return -1; 46 | } 47 | r = m.s + m.vec() * cr2 / cr1; 48 | return 1; 49 | } 50 | 51 | int crossSS(L l, L m, P& r) { 52 | int u = crossLL(l, m, r); 53 | if (u == 0) return 0; 54 | if (u == -1) { 55 | r = max(min(l.s, l.t), min(m.s, m.t)); 56 | P q = min(max(l.s, l.t), max(m.s, m.t)); 57 | return (q < r) ? 0 : (q == r ? 1 : -1); 58 | } 59 | if (ccw(l, r) == 0 && ccw(m, r) == 0) return 1; 60 | return 0; 61 | } 62 | -------------------------------------------------------------------------------- /src/geo/polygon.hpp: -------------------------------------------------------------------------------- 1 | using Pol = V

; 2 | 3 | D area2(const Pol& pol) { 4 | D u = 0; 5 | if (!pol.size()) return u; 6 | P a = pol.back(); 7 | for (auto b : pol) u += crs(a, b), a = b; 8 | return u; 9 | } 10 | 11 | // (1:left) | (2: right) is inside between v[i] ~ v[i + 1] 12 | V> insPolL(Pol pol, L l) { 13 | using Pi = pair; 14 | V v; 15 | P a, b = pol.back(); 16 | for (auto now: pol) { 17 | a = b; b = now; 18 | P p; 19 | if (crossLL({a, b}, l, p) != 1) continue; 20 | int sa = ccw(l, a) % 2, sb = ccw(l, b) % 2; 21 | if (sa > sb) swap(sa, sb); 22 | if (sa != 1 && sb == 1) v.push_back({p, 1}); 23 | if (sa == -1 && sb != -1) v.push_back({p, 2}); 24 | } 25 | sort(v.begin(), v.end(), [&](Pi x, Pi y){ 26 | return dot(l.vec(), x.first - l.s) < dot(l.vec(), y.first - l.s); 27 | }); 28 | int m = int(v.size()); 29 | V res; 30 | for (int i = 0; i < m; i++) { 31 | if (i) v[i].second ^= v[i - 1].second; 32 | if (!res.empty() && res.back().first == v[i].first) res.pop_back(); 33 | res.push_back(v[i]); 34 | } 35 | return res; 36 | } 37 | 38 | // 0: outside, 1: on line, 2: inside 39 | int contains(const Pol& pol, P p) { 40 | if (!pol.size()) return 0; 41 | int in = -1; 42 | P _a, _b = pol.back(); 43 | for (auto now : pol) { 44 | _a = _b; 45 | _b = now; 46 | P a = _a, b = _b; 47 | if (ccw(a, b, p) == 0) return 1; 48 | if (a.y > b.y) swap(a, b); 49 | if (!(a.y <= p.y && p.y < b.y)) continue; 50 | if (sgn(a.y, p.y) ? (crs(a - p, b - p) > 0) : (a.x > p.x)) in *= -1; 51 | } 52 | return in + 1; 53 | } 54 | 55 | // p must be sorted and uniqued! 56 | Pol convex_down(const V

& ps) { 57 | assert(ps.size() >= 2); 58 | Pol dw; 59 | for (P d : ps) { 60 | size_t n; 61 | while ((n = dw.size()) > 1) { 62 | // if (ccw(dw[n - 2], dw[n - 1], d) != -1) break; // line上も取る 63 | if (ccw(dw[n - 2], dw[n - 1], d) == 1) break; 64 | dw.pop_back(); 65 | } 66 | dw.push_back(d); 67 | } 68 | return dw; 69 | } 70 | 71 | Pol convex(V

ps) { 72 | sort(ps.begin(), ps.end()); 73 | ps.erase(unique(ps.begin(), ps.end()), ps.end()); 74 | if (ps.size() <= 1) return ps; 75 | Pol dw = convex_down(ps); 76 | reverse(ps.begin(), ps.end()); 77 | Pol up = convex_down(ps); 78 | dw.insert(dw.begin(), up.begin() + 1, up.end() - 1); 79 | return dw; 80 | } 81 | 82 | Pol convex_cut(const Pol& po, const L& l) { 83 | if (!po.size()) return Pol{}; 84 | Pol q; 85 | P a, b = po.back(); 86 | for (auto now : po) { 87 | a = b; 88 | b = now; 89 | if ((ccw(l, a) % 2) * (ccw(l, b) % 2) < 0) { 90 | P buf; 91 | crossLL(l, L(a, b), buf); 92 | q.push_back(buf); 93 | } 94 | if (ccw(l, b) != -1) q.push_back(b); 95 | } 96 | return q; 97 | } 98 | 99 | // pol must be convex 100 | D diameter(const Pol& p) { 101 | int n = int(p.size()); 102 | if (n == 2) return (p[1] - p[0]).abs(); 103 | int x = 0, y = 0; 104 | for (int i = 1; i < n; i++) { 105 | if (p[i] < p[x]) x = i; 106 | if (p[y] < p[i]) y = i; 107 | } 108 | D ans = 0; 109 | int sx = x, sy = y; 110 | /* 111 | do { 112 | ... 113 | } while (sx != x || sy != y); 114 | で1周する 115 | */ 116 | while (sx != y || sy != x) { 117 | ans = max(ans, (p[x] - p[y]).abs()); 118 | int nx = (x + 1 < n) ? x + 1 : 0, ny = (y + 1 < n) ? y + 1 : 0; 119 | if (crs(p[nx] - p[x], p[ny] - p[y]) < 0) 120 | x = nx; 121 | else 122 | y = ny; 123 | } 124 | return ans; 125 | } 126 | -------------------------------------------------------------------------------- /src/geo/primitive.hpp: -------------------------------------------------------------------------------- 1 | using D = double; 2 | const D PI = acos(D(-1)), EPS = 1e-10; 3 | 4 | int sgn(D a) { return (a < -EPS) ? -1 : (a > EPS); } 5 | int sgn(D a, D b) { return sgn(a - b); } 6 | struct P { 7 | D x, y; 8 | P(D _x = D(), D _y = D()) : x(_x), y(_y) {} 9 | P operator+(const P& r) const { return {x + r.x, y + r.y}; } 10 | P operator-(const P& r) const { return {x - r.x, y - r.y}; } 11 | P operator*(const P& r) const { 12 | return {x * r.x - y * r.y, x * r.y + y * r.x}; 13 | } 14 | 15 | P operator*(const D& r) const { return {x * r, y * r}; } 16 | P operator/(const D& r) const { return {x / r, y / r}; } 17 | 18 | P& operator+=(const P& r) { return *this = *this + r; } 19 | P& operator-=(const P& r) { return *this = *this - r; } 20 | P& operator*=(const P& r) { return *this = *this * r; } 21 | P& operator*=(const D& r) { return *this = *this * r; } 22 | P& operator/=(const D& r) { return *this = *this / r; } 23 | 24 | P operator-() const { return {-x, -y}; } 25 | 26 | bool operator<(const P& r) const { 27 | return 2 * sgn(x, r.x) + sgn(y, r.y) < 0; 28 | } 29 | bool operator==(const P& r) const { return sgn((*this - r).rabs()) == 0; } 30 | bool operator!=(const P& r) const { return !(*this == r); } 31 | 32 | D norm() const { return x * x + y * y; } 33 | D abs() const { return sqrt(norm()); } 34 | D rabs() const { return max(std::abs(x), std::abs(y)); } // robust abs 35 | D arg() const { return atan2(y, x); } 36 | 37 | pair to_pair() const { return {x, y}; } 38 | static P polar(D le, D th) { return {le * cos(th), le * sin(th)}; } 39 | }; 40 | ostream& operator<<(ostream& os, const P& p) { 41 | return os << "P(" << p.x << ", " << p.y << ")"; 42 | } 43 | 44 | struct L { 45 | P s, t; 46 | L(P _s = P(), P _t = P()) : s(_s), t(_t) {} 47 | P vec() const { return t - s; } 48 | D abs() const { return vec().abs(); } 49 | D arg() const { return vec().arg(); } 50 | }; 51 | ostream& operator<<(ostream& os, const L& l) { 52 | return os << "L(" << l.s << ", " << l.t << ")"; 53 | } 54 | 55 | D crs(P a, P b) { return a.x * b.y - a.y * b.x; } 56 | D dot(P a, P b) { return a.x * b.x + a.y * b.y; } 57 | // cross(a, b) is too small? 58 | int sgncrs(P a, P b) { 59 | D cr = crs(a, b); 60 | if (abs(cr) <= (a.rabs() + b.rabs()) * EPS) return 0; 61 | return (cr < 0) ? -1 : 1; 62 | } 63 | 64 | // -2, -1, 0, 1, 2 : front, clock, on, cclock, back 65 | int ccw(P b, P c) { 66 | int s = sgncrs(b, c); 67 | if (s) return s; 68 | if (!sgn(c.rabs()) || !sgn((c - b).rabs())) return 0; 69 | if (dot(b, c) < 0) return 2; 70 | if (dot(-b, c - b) < 0) return -2; 71 | return 0; 72 | } 73 | int ccw(P a, P b, P c) { return ccw(b - a, c - a); } 74 | int ccw(L l, P p) { return ccw(l.s, l.t, p); } 75 | -------------------------------------------------------------------------------- /src/geo/visualizer.hpp: -------------------------------------------------------------------------------- 1 | struct Vis { 2 | struct Col { 3 | int r, g, b; 4 | }; 5 | FILE* fp; 6 | D off, f; 7 | Vis(string s, D d, D u) : off(d), f(1000 / (u - d)) { 8 | fp = fopen(s.c_str(), "w"); 9 | fprintf( 10 | fp, 11 | "" 42 | "" 43 | ""); 44 | fclose(fp); 45 | } 46 | }; 47 | -------------------------------------------------------------------------------- /src/graph/articulation.hpp: -------------------------------------------------------------------------------- 1 | struct Articulation { 2 | VV tr; 3 | }; 4 | 5 | template struct ArticulationExec : Articulation { 6 | const VV& g; 7 | int n; 8 | int ordc = 0; 9 | V low, ord; 10 | V used; 11 | AriticulationExec(const VV& _g) 12 | : g(_g), n(int(g.size())), low(n), ord(n), used(n) { 13 | tr = VV(n); 14 | for (int i = 0; i < n; i++) { 15 | if (used[i]) continue; 16 | dfs1(i, -1); 17 | dfs2(i, -1); 18 | } 19 | } 20 | void dfs1(int p, int b) { 21 | used[p] = 1; 22 | low[p] = ord[p] = ordc++; 23 | bool rt = true; 24 | for (auto e : g[p]) { 25 | int d = e.to; 26 | if (rt && d == b) { 27 | rt = false; 28 | continue; 29 | } 30 | if (!used[d]) { 31 | dfs1(d, p); 32 | low[p] = min(low[p], low[d]); 33 | } else { 34 | low[p] = min(low[p], ord[d]); 35 | } 36 | } 37 | } 38 | void dfs2(int p, int bid = -1) { 39 | used[p] = 2; 40 | if (bid != -1) { 41 | tr[p].push_back(bid); 42 | tr[bid].push_back(p); 43 | } 44 | for (auto e: g[p]) { 45 | int d = e.to; 46 | if (used[d] == 2) continue; 47 | if (low[d] < ord[p]) { 48 | dfs2(d, bid); 49 | continue; 50 | } 51 | int nid = int(tr.size()); 52 | tr.push_back({}); 53 | tr[p].push_back(nid); 54 | tr[nid].push_back(p); 55 | dfs2(d, nid); 56 | } 57 | } 58 | }; 59 | 60 | template Articulation get_articulation(const VV& g) { 61 | return ArticulationExec(g); 62 | } 63 | -------------------------------------------------------------------------------- /src/graph/balancedseparator.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "base.hpp" 4 | #include "graph/primitive.hpp" 5 | #include "graph/treedecomp.hpp" 6 | #include "tree/centroid.hpp" 7 | 8 | struct BalancedSeparator { 9 | int num_layer; 10 | VV tr; 11 | VV bags; 12 | V lv; 13 | V pos; 14 | V par; 15 | 16 | // lca bag of vertex u, v 17 | int lca(int u, int v) const { 18 | u = pos[u]; v = pos[v]; 19 | while (u != v) { 20 | // dbg(u, v, lv[u], lv[v], par[u], par[v]); 21 | if (lv[u] < lv[v]) swap(u, v); 22 | u = par[u]; 23 | } 24 | return u; 25 | } 26 | }; 27 | 28 | BalancedSeparator balanced_separator(const TreeDecomp& td) { 29 | int n = 0; 30 | for (auto bag: td.bags) { 31 | for (auto v: bag) { 32 | n = max(n, v + 1); 33 | } 34 | } 35 | BalancedSeparator bs; 36 | bs.pos = V(n, -1); 37 | 38 | auto cent = get_centroid(td.tr); 39 | 40 | auto cdfs = [&](auto self, int p, int bk_id, int now_lv) -> int { 41 | int id = int(bs.tr.size()); 42 | bs.tr.push_back({}); 43 | bs.bags.push_back({}); 44 | bs.par.push_back(bk_id); 45 | bs.lv.push_back(now_lv); 46 | for (auto v : td.bags[p]) { 47 | if (bs.pos[v] != -1) continue; 48 | bs.pos[v] = id; 49 | bs.bags[id].push_back(v); 50 | } 51 | 52 | for (int d : cent.tr[p]) { 53 | int cid = self(self, d, id, now_lv + 1); 54 | bs.tr[id].push_back({cid}); 55 | } 56 | return id; 57 | }; 58 | cdfs(cdfs, cent.r, -1, 0); 59 | bs.num_layer = 0; 60 | for (int x: bs.lv) bs.num_layer = max(bs.num_layer, x + 1); 61 | 62 | return bs; 63 | } 64 | -------------------------------------------------------------------------------- /src/graph/bidirectedcut.hpp: -------------------------------------------------------------------------------- 1 | template 2 | struct BidirectedCut { 3 | D sum = INF; 4 | template 5 | BidirectedCut(VV g) { 6 | int n = (int)g.size(); 7 | int m_a = -1, m_b = -1; 8 | V dist_base(n, 0); 9 | for (int m = n; m > 1; m--) { 10 | int a, b; 11 | auto dist = dist_base; 12 | for (int i = 0; i < m; i++) { 13 | a = b; b = max_element(begin(dist), end(dist)) - begin(dist); 14 | if (i == m-1) sum = min(sum, dist[b]); 15 | dist[b] = -INF; 16 | for (E &e: g[b]) { 17 | if (e.to == m_b) e.to = m_a; 18 | if (dist[e.to] == -INF) continue; 19 | dist[e.to] += e.dist; 20 | } 21 | } 22 | //merge a, b 23 | m_a = a; m_b = b; 24 | g[a].insert(end(g[a]), begin(g[b]), end(g[b])); 25 | g[b].clear(); 26 | dist_base[b] = -INF; 27 | } 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /src/graph/bimaching.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "datastructure/simplequeue.hpp" 4 | #include "graph/csr.hpp" 5 | 6 | struct BipartiteMaching { 7 | public: 8 | int n, m; 9 | V lmt, rmt; 10 | 11 | BipartiteMaching(int _n, int _m, V> edges) 12 | : n(_n), m(_m), lmt(n, -1), rmt(m, -1), dist(m) { 13 | for (auto e : edges) { 14 | int l, r; 15 | tie(l, r) = e; 16 | if (lmt[l] == -1 && rmt[r] == -1) { 17 | lmt[l] = r; 18 | rmt[r] = l; 19 | } 20 | } 21 | lg = CSR(n, edges); 22 | for (auto& e : edges) swap(e.first, e.second); 23 | rg = CSR(m, edges); 24 | 25 | while (true) { 26 | bfs(); 27 | // if (trg_dist >= 20) break; 28 | if (trg_dist == TEN(9)) break; 29 | bool f = dfs(); 30 | assert(f); 31 | } 32 | } 33 | 34 | private: 35 | CSR lg, rg; 36 | 37 | int trg_dist; 38 | V dist; 39 | SimpleQueue que; 40 | void bfs() { 41 | trg_dist = TEN(9); 42 | que.clear(); 43 | for (int i = 0; i < m; i++) { 44 | if (rmt[i] == -1) { 45 | dist[i] = 0; 46 | que.push(i); 47 | } else { 48 | dist[i] = TEN(9); 49 | } 50 | } 51 | while (!que.empty()) { 52 | int q = que.front(); 53 | que.pop(); 54 | int distq = dist[q]; 55 | for (int pid = rg.start[q]; pid < rg.start[q + 1]; pid++) { 56 | int p = rg.to[pid]; 57 | int next = lmt[p]; 58 | if (next == -1) { 59 | trg_dist = distq + 1; 60 | return; 61 | } 62 | if (dist[next] == TEN(9)) { 63 | dist[next] = distq + 1; 64 | que.push(next); 65 | } 66 | } 67 | } 68 | } 69 | bool dfs() { 70 | bool update = false; 71 | for (int i = 0; i < n; i++) { 72 | if (lmt[i] == -1 && dfs(i, trg_dist)) { 73 | update = true; 74 | } 75 | } 76 | return update; 77 | } 78 | bool dfs(int p, int distp) { 79 | int st = lg.start[p], ls = lg.start[p + 1]; 80 | for (int qid = st; qid < ls; qid++) { 81 | int q = lg.to[qid]; 82 | if (distp - 1 == dist[q]) { 83 | int next = rmt[q]; 84 | if (next != -1) { 85 | dist[q] = TEN(9); 86 | if (!dfs(next, distp - 1)) continue; 87 | } 88 | lmt[p] = q; 89 | rmt[q] = p; 90 | return true; 91 | } 92 | } 93 | return false; 94 | } 95 | }; 96 | -------------------------------------------------------------------------------- /src/graph/bridge.hpp: -------------------------------------------------------------------------------- 1 | struct Bridge { 2 | V id; 3 | VV groups; 4 | VV tr; 5 | }; 6 | 7 | template struct BridgeExec : Bridge { 8 | const VV& g; 9 | int n; 10 | int ordc = 0; 11 | V low, ord, vlist; 12 | V used; 13 | BridgeExec(const VV& _g) 14 | : g(_g), n(int(g.size())), low(n), ord(n), used(n) { 15 | id = V(n); 16 | for (int i = 0; i < n; i++) { 17 | if (used[i]) continue; 18 | dfs1(i, -1); 19 | dfs2(i, -1); 20 | } 21 | } 22 | void dfs1(int p, int b) { 23 | used[p] = 1; 24 | low[p] = ord[p] = ordc++; 25 | vlist.push_back(p); 26 | bool rt = true; 27 | for (auto e : g[p]) { 28 | int d = e.to; 29 | if (rt && d == b) { 30 | rt = false; 31 | continue; 32 | } 33 | if (!used[d]) { 34 | dfs1(d, p); 35 | low[p] = min(low[p], low[d]); 36 | } else { 37 | low[p] = min(low[p], ord[d]); 38 | } 39 | } 40 | } 41 | void dfs2(int p, int b) { 42 | used[p] = 2; 43 | bool is_root = low[p] == ord[p]; 44 | if (is_root) { 45 | int idc = int(groups.size()); 46 | id[p] = idc; 47 | groups.push_back({p}); 48 | tr.push_back({}); 49 | if (b != -1) { 50 | tr[idc].push_back(id[b]); 51 | tr[id[b]].push_back(idc); 52 | } 53 | } else { 54 | id[p] = id[b]; 55 | groups[id[p]].push_back(p); 56 | } 57 | for (auto e : g[p]) { 58 | int d = e.to; 59 | if (d == b || used[d] == 2) continue; 60 | dfs2(d, p); 61 | } 62 | } 63 | }; 64 | 65 | template Bridge get_bridge(const VV& g) { 66 | return BridgeExec(g); 67 | } 68 | -------------------------------------------------------------------------------- /src/graph/csr.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct CSR { 4 | V to, start; 5 | CSR() {} 6 | CSR(int n, const V>& edges) { 7 | start = V(n + 1); 8 | for (auto e : edges) { 9 | start[e.first]++; 10 | } 11 | for (int i = 1; i <= n; i++) { 12 | start[i] += start[i - 1]; 13 | } 14 | to = V(start.back()); 15 | for (auto e : edges) { 16 | to[start[e.first] - 1] = e.second; 17 | start[e.first]--; 18 | } 19 | } 20 | }; 21 | -------------------------------------------------------------------------------- /src/graph/dijkstra.hpp: -------------------------------------------------------------------------------- 1 | template struct MinDist { 2 | V dist; 3 | V from; 4 | }; 5 | 6 | template 7 | MinDist mindist(const VV& g, int s, D inf = numeric_limits::max()) { 8 | int n = (int)g.size(); 9 | V dist = V(n, inf); 10 | V from = V(n); 11 | struct P { 12 | D key; 13 | int to; 14 | bool operator<(P r) const { return key > r.key; } 15 | }; 16 | priority_queue

q; 17 | q.push(P{0, s}); 18 | dist[s] = D(0); 19 | while (!q.empty()) { 20 | P p = q.top(); 21 | q.pop(); 22 | if (dist[p.to] < p.key) continue; 23 | for (E e : g[p.to]) { 24 | if (p.key + e.dist < dist[e.to]) { 25 | dist[e.to] = p.key + e.dist; 26 | from[e.to] = p.to; 27 | q.push(P{dist[e.to], e.to}); 28 | } 29 | } 30 | } 31 | return MinDist{dist, from}; 32 | } 33 | -------------------------------------------------------------------------------- /src/graph/directedmst.hpp: -------------------------------------------------------------------------------- 1 | template 2 | struct DirectedMST { 3 | decltype(E::dist) cost = 0; 4 | V mine; // min edge 5 | DirectedMST(const Graph &g, int r) { 6 | int n = (int)g.size(); 7 | mine = vector(n); 8 | for (int i = 0; i < n; i++) { 9 | if (i == r) continue; 10 | assert((int)g[i].size()); 11 | mine[i] = *min_element(g[i].begin(), g[i].end(), 12 | [](const E &l, const E &r){return l.dist < r.dist;}); 13 | cost += mine[i].dist; 14 | } 15 | V i2g(n, -1); i2g[r] = 0; 16 | int gc = 1; 17 | for (int i = 0; i < n; i++) { 18 | if (i2g[i] != -1) continue; 19 | int j = i; 20 | do { 21 | i2g[j] = gc++; 22 | } while (j = mine[j].to, i2g[j] == -1); 23 | if (i2g[j] < i2g[i]) continue; 24 | //roop 25 | int k = j; 26 | do { 27 | i2g[k] = i2g[j]; 28 | } while(k = mine[k].to, k != j); 29 | gc = i2g[j]+1; 30 | } 31 | if (gc == n) return; 32 | Graph ng(gc); 33 | for (int i = 0; i < n; i++) { 34 | if (i == r) continue; 35 | for (E e: g[i]) { 36 | if (i2g[e.to] == i2g[i]) continue; 37 | e.to = i2g[e.to]; 38 | e.dist -= mine[i].dist; 39 | ng[i2g[i]].push_back(e); 40 | } 41 | } 42 | auto nme = DirectedMST(ng, 0).mine; 43 | vector ok(gc, false); 44 | for (int i = 0; i < n; i++) { 45 | if (i == r or ok[i2g[i]]) continue; 46 | for (E e: g[i]) { 47 | if (e.dist - mine[i].dist == nme[i2g[i]].dist) { 48 | ok[i2g[i]] = true; 49 | mine[i] = e; 50 | cost += nme[i2g[i]].dist; 51 | break; 52 | } 53 | } 54 | } 55 | } 56 | }; 57 | -------------------------------------------------------------------------------- /src/graph/dominator.hpp: -------------------------------------------------------------------------------- 1 | struct Dominator { 2 | V idom, sdom; 3 | LowLink lc; 4 | Dominator() {} 5 | template 6 | Dominator(const VV &g, const VV &rg, int s) { 7 | lc = LowLink(g, s); 8 | int n = (int)g.size(); 9 | 10 | // uf init 11 | p.resize(n); mv.resize(n); 12 | fill_n(p.begin(), n, -1); 13 | iota(mv.begin(), mv.end(), 0); 14 | idom = vector(n, -1); 15 | sdom = vector(n); 16 | iota(sdom.begin(), sdom.end(), 0); 17 | 18 | vector up(n); 19 | vector> bucket(n); 20 | int U = int(lc.vlis.size()); 21 | for (int i = U-1; i > 0; i--) { 22 | int u = lc.vlis[i]; 23 | for (E e: rg[u]) { 24 | if (lc.ord[e.to] == -1) continue; 25 | sdom[u] = lc.vlis[min(lc.ord[sdom[u]], lc.ord[sdom[compress(e.to)]])]; 26 | } 27 | bucket[sdom[u]].push_back(u); 28 | for (int v: bucket[lc.par[u]]) { 29 | up[v] = compress(v); 30 | } 31 | bucket[lc.par[u]].clear(); 32 | p[u] = lc.par[u]; // uf merge 33 | } 34 | 35 | for (int i = 1; i < U; i++) { 36 | int u = lc.vlis[i], v = up[u]; 37 | if (sdom[u] == sdom[v]) idom[u] = sdom[u]; 38 | else idom[u] = idom[v]; 39 | } 40 | } 41 | 42 | // unionfind 43 | V p, mv; // parent, min sdom's v 44 | int compress(int a) { 45 | if (p[a] != -1) { 46 | compress(p[a]); 47 | if (lc.ord[sdom[mv[a]]] > lc.ord[sdom[mv[p[a]]]]) { 48 | mv[a] = mv[p[a]]; 49 | } 50 | p[a] = (p[p[a]] == -1 ? p[a] : p[p[a]]); 51 | } 52 | return mv[a]; 53 | } 54 | }; 55 | -------------------------------------------------------------------------------- /src/graph/hungarian.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | 割当問題を解き,以下の条件を満たすle, ri, permを得る 3 | - le[i] <= 0, ri[j] >= 0 4 | - cost[i][j] + le[i] + ri[j] >= 0 5 | - cost[i][perm[i]] + le[i] + ri[perm[i]] = 0 6 | */ 7 | template 8 | struct Hungarian { 9 | V le, ri; 10 | V perm; 11 | 12 | Hungarian(const VV& c) { 13 | int n = int(c.size()), m = int(c[0].size()); 14 | assert(n <= m); 15 | le = V(n, D(0)); ri = V(m, D(0)); 16 | perm = V(n); 17 | V to_r(n, -1), to_l(m, -1); 18 | 19 | for (int s = 0; s < n; s++) { 20 | V l_u(n), r_u(m); 21 | l_u[s] = true; 22 | V tr(m, -1), min_l(m, s); 23 | V min_cost(m); 24 | for (int j = 0; j < m; j++) min_cost[j] = c[s][j] + le[s] + ri[j]; 25 | while (true) { 26 | int r = -1; 27 | D d = numeric_limits::max(); 28 | for (int j = 0; j < m; j++) { 29 | if (!r_u[j] && min_cost[j] < d) { 30 | r = j; 31 | d = min_cost[j]; 32 | } 33 | } 34 | for (int i = 0; i < n; i++) if (l_u[i]) le[i] -= d; 35 | for (int j = 0; j < m; j++) { 36 | if (r_u[j]) ri[j] += d; 37 | else min_cost[j] -= d; 38 | } 39 | tr[r] = min_l[r]; 40 | int l = to_l[r]; 41 | if (l == -1) { 42 | while (r != -1) { 43 | int nl = tr[r], nr = to_r[nl]; 44 | to_l[r] = nl; to_r[nl] = r; 45 | r = nr; 46 | } 47 | break; 48 | } 49 | l_u[l] = r_u[r] = true; 50 | for (int j = 0; j < m; j++) { 51 | D cost = c[l][j] + le[l] + ri[j]; 52 | if (cost < min_cost[j]) { 53 | min_l[j] = l; 54 | min_cost[j] = cost; 55 | } 56 | } 57 | } 58 | } 59 | perm = to_r; 60 | } 61 | }; 62 | -------------------------------------------------------------------------------- /src/graph/manhattanmst.hpp: -------------------------------------------------------------------------------- 1 | template 2 | V> manhattan_mst(V> ps, 3 | T inf = numeric_limits::max()) { 4 | V> edges; 5 | int n = int(ps.size()); 6 | V ids(n); 7 | iota(ids.begin(), ids.end(), 0); 8 | for (int ph = 0; ph < 4; ph++) { 9 | sort(ids.begin(), ids.end(), [&](auto i, auto j) { 10 | T ixy = (ps[i].first + ps[i].second), 11 | jxy = (ps[j].first + ps[j].second); 12 | return tie(ixy, ps[i].second) > tie(jxy, ps[j].second); 13 | }); 14 | V xv; 15 | for (int i = 0; i < n; i++) xv.push_back(ps[i].first); 16 | sort(xv.begin(), xv.end()); 17 | xv.erase(unique(xv.begin(), xv.end()), xv.end()); 18 | using P = pair; 19 | V

fen(n, P(-inf, -1)); 20 | for (int id : ids) { 21 | auto xi = int(lower_bound(xv.begin(), xv.end(), ps[id].first) - 22 | xv.begin()); 23 | P ma = P(-inf, -1); 24 | { 25 | int i = xi + 1; 26 | while (i > 0) { 27 | if (ma.first <= fen[i - 1].first) ma = fen[i - 1]; 28 | i -= i & -i; 29 | } 30 | } 31 | if (ma.second != -1) edges.push_back({id, ma.second}); 32 | { 33 | T x = ps[id].first - ps[id].second; 34 | int i = xi + 1; 35 | while (i <= n) { 36 | if (fen[i - 1].first <= x) fen[i - 1] = P(x, id); 37 | i += i & -i; 38 | } 39 | } 40 | } 41 | 42 | for (auto& p : ps) { 43 | swap(p.first, p.second); 44 | } 45 | if (ph == 1) { 46 | for (auto& p : ps) { 47 | p.second *= -1; 48 | } 49 | } 50 | } 51 | auto dist = [&](int i, int j) { 52 | return abs(ps[i].first - ps[j].first) + 53 | abs(ps[i].second - ps[j].second); 54 | }; 55 | sort(edges.begin(), edges.end(), [&](auto x, auto y) { 56 | return dist(x.first, x.second) < dist(y.first, y.second); 57 | }); 58 | auto uf = UnionFind(n); 59 | V> res; 60 | for (auto p : edges) { 61 | if (uf.same(p.first, p.second)) continue; 62 | res.push_back(p); 63 | uf.merge(p.first, p.second); 64 | } 65 | return res; 66 | } 67 | -------------------------------------------------------------------------------- /src/graph/matroidintersection.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /* 4 | elements: matroid elements 5 | on: used elements 6 | f: lambda, f(on, g1(i, j), g2(i, j))と呼ばれるので 7 | そのまま足せる要素についてg(i, -1)を呼び、交換できるペアについてg(i, j)を呼ぶ 8 | */ 9 | template 10 | bool matroid_intersection(const V& elements, V& on, F& f) { 11 | int m = int(elements.size()); 12 | assert(int(on.size()) == m); 13 | VV g(m); 14 | V st(m), ed(m); 15 | f(on, 16 | [&](int u, int v) { 17 | assert(0 <= u && u < m && !on[u]); 18 | if (v == -1) 19 | st[u] = true; 20 | else { 21 | assert(0 <= v && v < m && on[v]); 22 | g[v].push_back(u); 23 | } 24 | }, 25 | [&](int u, int v) { 26 | assert(0 <= u && u < m && !on[u]); 27 | if (v == -1) 28 | ed[u] = true; 29 | else { 30 | assert(0 <= v && v < m && on[v]); 31 | g[u].push_back(v); 32 | } 33 | }); 34 | V prev(m, -1); 35 | V dist(m, TEN(9)); 36 | queue que; 37 | for (int i = 0; i < m; i++) { 38 | if (st[i]) { 39 | dist[i] = 0; 40 | que.push(i); 41 | } 42 | } 43 | 44 | while (que.size()) { 45 | int p = que.front(); 46 | que.pop(); 47 | if (ed[p]) { 48 | int now = p; 49 | while (now != -1) { 50 | on[now] = !on[now]; 51 | now = prev[now]; 52 | } 53 | return true; 54 | } 55 | for (int d : g[p]) { 56 | if (dist[d] > dist[p] + 1) { 57 | dist[d] = dist[p] + 1; 58 | prev[d] = p; 59 | que.push(d); 60 | } 61 | } 62 | } 63 | return false; 64 | } 65 | template 66 | V matroid_intersection(const V& elements, F f) { 67 | int m = int(elements.size()); 68 | V on(m); 69 | while (matroid_intersection(elements, on, f)) { 70 | } 71 | return on; 72 | } 73 | 74 | /* 75 | void CFHello2020G { 76 | // forest * choise 77 | auto used = 78 | matroid_intersection(es, [&](const V& on, auto g1, auto g2) { 79 | auto base = UnionFind(n); 80 | V cnt(n); 81 | for (int l = 0; l < m; l++) { 82 | if (!on[l]) continue; 83 | base.merge(es[l].from, es[l].to); 84 | cnt[es[l].id]++; 85 | } 86 | for (int r = 0; r < m; r++) { 87 | if (on[r]) continue; 88 | if (!base.same(es[r].from, es[r].to)) g1(r, -1); 89 | if (cnt[es[r].id] == 0) g2(r, -1); 90 | } 91 | for (int l = 0; l < m; l++) { 92 | if (!on[l]) continue; 93 | auto uf = UnionFind(n); 94 | for (int i = 0; i < m; i++) { 95 | if (!on[i] || i == l) continue; 96 | uf.merge(es[i].from, es[i].to); 97 | } 98 | for (int r = 0; r < m; r++) { 99 | if (on[r]) continue; 100 | if (!uf.same(es[r].from, es[r].to)) g1(r, l); 101 | if (es[l].id == es[r].id) g2(r, l); 102 | } 103 | } 104 | }); 105 | }*/ 106 | -------------------------------------------------------------------------------- /src/graph/maxclique.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "base.hpp" 4 | 5 | template struct MaxClique { 6 | using B = bitset; 7 | int n; 8 | V g, col_buf; 9 | V clique, now; 10 | struct P { 11 | int id, col, deg; 12 | }; 13 | VV

rems; 14 | void dfs(int dps = 0) { 15 | if (clique.size() < now.size()) clique = now; 16 | auto& rem = rems[dps]; 17 | sort(rem.begin(), rem.end(), [&](P a, P b) { return a.deg > b.deg; }); 18 | int max_c = 1; 19 | for (auto& p : rem) { 20 | p.col = 0; 21 | while ((g[p.id] & col_buf[p.col]).any()) p.col++; 22 | max_c = max(max_c, p.id + 1); 23 | col_buf[p.col].set(p.id); 24 | } 25 | for (int i = 0; i < max_c; i++) col_buf[i].reset(); 26 | sort(rem.begin(), rem.end(), [&](P a, P b) { return a.col < b.col; }); 27 | 28 | while (!rem.empty()) { 29 | auto p = rem.back(); 30 | if (now.size() + p.col + 1 <= clique.size()) break; 31 | 32 | auto& nrem = rems[dps + 1]; 33 | nrem.clear(); 34 | B bs = B(); 35 | for (auto q : rem) { 36 | if (g[p.id][q.id]) { 37 | nrem.push_back({q.id, -1, 0}); 38 | bs.set(q.id); 39 | } 40 | } 41 | for (auto& q : nrem) { 42 | q.deg = int((bs & g[q.id]).count()); 43 | } 44 | now.push_back(p.id); 45 | dfs(dps + 1); 46 | now.pop_back(); 47 | 48 | rem.pop_back(); 49 | } 50 | } 51 | 52 | MaxClique(VV _g) : n(int(_g.size())), g(n), col_buf(n), rems(n + 1) { 53 | for (int i = 0; i < n; i++) { 54 | rems[0].push_back({i, -1, int(_g[i].size())}); 55 | for (auto e : _g[i]) g[i][e.to] = 1; 56 | } 57 | dfs(); 58 | } 59 | }; 60 | -------------------------------------------------------------------------------- /src/graph/maxflow.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | struct E { 3 | int to, rev, cap; 4 | }; 5 | VV g; 6 | auto add_edge = [&](int from, int to, int cap) { 7 | g[from].push_back(E{to, int(g[to].size()), cap}); 8 | g[to].push_back(E{from, int(g[from].size())-1, 0}); 9 | }; 10 | */ 11 | 12 | template 13 | struct MaxFlow { 14 | C flow; 15 | V dual; // false: S-side true: T-side 16 | }; 17 | 18 | template 19 | struct MFExec { 20 | static constexpr C INF = numeric_limits::max(); 21 | C eps; 22 | VV& g; 23 | int s, t; 24 | V level, iter; 25 | 26 | C dfs(int v, C f) { 27 | if (v == t) return f; 28 | C res = 0; 29 | for (int& i = iter[v]; i < int(g[v].size()); i++) { 30 | E& e = g[v][i]; 31 | if (e.cap <= eps || level[v] >= level[e.to]) continue; 32 | C d = dfs(e.to, min(f, e.cap)); 33 | e.cap -= d; 34 | g[e.to][e.rev].cap += d; 35 | res += d; 36 | f -= d; 37 | if (f == 0) break; 38 | } 39 | return res; 40 | } 41 | 42 | MaxFlow info; 43 | MFExec(VV& _g, int _s, int _t, C _eps) 44 | : eps(_eps), g(_g), s(_s), t(_t) { 45 | int N = int(g.size()); 46 | 47 | C& flow = (info.flow = 0); 48 | while (true) { 49 | queue que; 50 | level = V(N, -1); 51 | level[s] = 0; 52 | que.push(s); 53 | while (!que.empty()) { 54 | int v = que.front(); que.pop(); 55 | for (E e: g[v]) { 56 | if (e.cap <= eps || level[e.to] >= 0) continue; 57 | level[e.to] = level[v] + 1; 58 | que.push(e.to); 59 | } 60 | } 61 | if (level[t] == -1) break; 62 | iter = V(N, 0); 63 | while (true) { 64 | C f = dfs(s, INF); 65 | if (!f) break; 66 | flow += f; 67 | } 68 | } 69 | for (int i = 0; i < N; i++) info.dual.push_back(level[i] == -1); 70 | } 71 | }; 72 | 73 | template 74 | MaxFlow get_mf(VV& g, int s, int t, C eps) { 75 | return MFExec(g, s, t, eps).info; 76 | } 77 | -------------------------------------------------------------------------------- /src/graph/mincostflow.hpp: -------------------------------------------------------------------------------- 1 | /* 2 | struct E { 3 | int to, rev, cap, dist; 4 | }; 5 | VV g; 6 | auto add_edge = [&](int from, int to, int cap, int dist) { 7 | g[from].push_back(E{to, int(g[to].size()), cap, dist}); 8 | g[to].push_back(E{from, int(g[from].size())-1, 0, -dist}); 9 | }; 10 | 11 | auto res = min_cost_flow(g, s, t, false); 12 | res.max_flow(TEN(9)); 13 | 14 | // cap_flow : 最大流量 15 | // flow : 最小費用 16 | */ 17 | 18 | template 19 | struct MinCostFlow { 20 | static constexpr D INF = numeric_limits::max(); 21 | int n; 22 | VV g; 23 | int s, t; 24 | C nc, cap_flow = 0; 25 | D nd, flow = 0; 26 | 27 | V dual; 28 | V pv, pe; 29 | 30 | MinCostFlow(VV _g, int _s, int _t, bool neg) 31 | : n(int(_g.size())), g(_g), s(_s), t(_t) { 32 | assert(s != t); 33 | dual = V(n); 34 | pv = pe = V(n); 35 | if (neg) { 36 | V dist(n, D(INF)); 37 | dist[s] = 0; 38 | for (int ph = 0; ph < n; ph++) { 39 | bool update = false; 40 | for (int i = 0; i < n; i++) { 41 | if (dist[i] == INF) continue; 42 | for (auto e: g[i]) { 43 | if (!e.cap) continue; 44 | if (dist[i] + e.dist < dist[e.to]) { 45 | dist[e.to] = dist[i] + e.dist; 46 | update = true; 47 | } 48 | } 49 | } 50 | if (!update) break; 51 | } 52 | for (int v = 0; v < n; v++) { 53 | dual[v] += dist[v]; 54 | } 55 | } 56 | dual_ref(); 57 | } 58 | 59 | C single_flow(C c) { 60 | if (nd == INF) return nc; 61 | c = min(c, nc); 62 | for (int v = t; v != s; v = pv[v]) { 63 | E& e = g[pv[v]][pe[v]]; 64 | e.cap -= c; 65 | g[v][e.rev].cap += c; 66 | } 67 | cap_flow += c; 68 | flow += nd * c; 69 | nc -= c; 70 | if (!nc) dual_ref(); 71 | return c; 72 | } 73 | 74 | void max_flow(C c) { 75 | while (c) { 76 | C f = single_flow(c); 77 | if (!f) break; 78 | c -= f; 79 | } 80 | } 81 | 82 | void dual_ref() { 83 | V dist(g.size(), D(INF)); 84 | pv = pe = V(n, -1); 85 | struct Q { 86 | D key; 87 | int to; 88 | bool operator<(Q r) const { return key > r.key; } 89 | }; 90 | priority_queue que; 91 | dist[s] = 0; 92 | que.push(Q{D(0), s}); 93 | V vis(n); 94 | while (!que.empty()) { 95 | int v = que.top().to; que.pop(); 96 | if (v == t) break; 97 | if (vis[v]) continue; 98 | vis[v] = true; 99 | for (int i = 0; i < int(g[v].size()); i++) { 100 | E e = g[v][i]; 101 | if (vis[e.to] || !e.cap) continue; 102 | D cost = dist[v] + e.dist + dual[v] - dual[e.to]; 103 | if (dist[e.to] > cost) { 104 | dist[e.to] = cost; 105 | pv[e.to] = v; pe[e.to] = i; 106 | que.push(Q{dist[e.to], e.to}); 107 | } 108 | } 109 | } 110 | if (dist[t] == INF) { 111 | nd = INF; nc = 0; 112 | return; 113 | } 114 | for (int v = 0; v < n; v++) { 115 | if (!vis[v]) continue; 116 | dual[v] += dist[v] - dist[t]; 117 | } 118 | nd = dual[t] - dual[s]; 119 | nc = numeric_limits::max(); 120 | for (int v = t; v != s; v = pv[v]) { 121 | nc = min(nc, g[pv[v]][pe[v]].cap); 122 | } 123 | } 124 | }; 125 | 126 | template 127 | MinCostFlow get_mcf(const VV& g, int s, int t, bool neg = false) { 128 | return MinCostFlow(g, s, t, neg); 129 | } 130 | -------------------------------------------------------------------------------- /src/graph/primitive.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct SimpleEdge { 4 | int to; 5 | }; 6 | ostream& operator<<(ostream& os, const SimpleEdge& e) { 7 | return os << "E(" << e.to << ")"; 8 | } 9 | -------------------------------------------------------------------------------- /src/graph/retrograde.hpp: -------------------------------------------------------------------------------- 1 | /** 2 | * d[i] = 3 | * -1:このマスからスタートすると先手が負ける 4 | * 0:? 5 | * 1:このマスからスタートすると先手が勝つ 6 | */ 7 | template 8 | void retrograde(const Graph &g, const Graph &rg, vector &d) { 9 | int V = (int)g.size(); 10 | vector count(V); 11 | for (int i = 0; i < V; i++) { 12 | count[i] = (int)g[i].size(); 13 | } 14 | for (int i = 0; i < V; i++) { 15 | if (d[i] == 1) { 16 | for (E e: rg[i]) { 17 | count[e.to]--; 18 | } 19 | } 20 | } 21 | for (int i = 0; i < V; i++) { 22 | if (d[i] == -1) { 23 | for (E e: rg[i]) { 24 | if (d[e.to]) continue; 25 | d[e.to] = 1; 26 | for (E f: rg[e.to]) { 27 | count[f.to]--; 28 | } 29 | } 30 | } 31 | } 32 | queue q; 33 | for (int i = 0; i < V; i++) { 34 | if (count[i]) continue; 35 | q.push(i); 36 | } 37 | while (q.size()) { 38 | int p = q.front(); q.pop(); 39 | if (d[p]) continue; 40 | d[p] = -1; 41 | for (E e: rg[p]) { 42 | if (d[e.to]) continue; 43 | d[e.to] = 1; 44 | for (E f: rg[e.to]) { 45 | count[f.to]--; 46 | if (!count[f.to]) { 47 | q.push(f.to); 48 | } 49 | } 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/graph/scc.hpp: -------------------------------------------------------------------------------- 1 | struct SCC { 2 | V id; 3 | VV groups; 4 | }; 5 | 6 | template struct SCCExec : SCC { 7 | int n; 8 | const VV& g; 9 | int tm = 0; 10 | V flag; 11 | V low, ord, st; 12 | void dfs(int v) { 13 | low[v] = ord[v] = tm++; 14 | st.push_back(v); 15 | flag[v] = true; 16 | for (auto e : g[v]) { 17 | if (ord[e.to] == -1) { 18 | dfs(e.to); 19 | low[v] = min(low[v], low[e.to]); 20 | } else if (flag[e.to]) { 21 | low[v] = min(low[v], ord[e.to]); 22 | } 23 | } 24 | if (low[v] == ord[v]) { 25 | V gr; 26 | while (true) { 27 | int u = st.back(); 28 | st.pop_back(); 29 | gr.push_back(u); 30 | if (u == v) break; 31 | } 32 | for (int x : gr) flag[x] = false; 33 | groups.push_back(gr); 34 | } 35 | } 36 | SCCExec(const VV& _g) 37 | : n(int(_g.size())), g(_g), flag(n), low(n), ord(n, -1) { 38 | id = V(n); 39 | for (int i = 0; i < n; i++) { 40 | if (ord[i] == -1) dfs(i); 41 | } 42 | reverse(groups.begin(), groups.end()); 43 | for (int i = 0; i < int(groups.size()); i++) { 44 | for (int x : groups[i]) { 45 | id[x] = i; 46 | } 47 | } 48 | } 49 | }; 50 | 51 | template SCC get_scc(const VV& g) { return SCCExec(g); } 52 | 53 | template struct BitsetSCCExec : SCC { 54 | using B = bitset; 55 | int n; 56 | const V& g; 57 | const V& rg; 58 | V vs; 59 | B unvis; 60 | void dfs(int v) { 61 | unvis.reset(v); 62 | while (true) { 63 | int d = (unvis & g[v])._Find_first(); 64 | if (d >= n) break; 65 | dfs(d); 66 | } 67 | vs.push_back(v); 68 | } 69 | 70 | void rdfs(int v, int k) { 71 | unvis.reset(v); 72 | id[v] = k; 73 | groups[k].push_back(v); 74 | while (true) { 75 | int d = (unvis & rg[v])._Find_first(); 76 | if (d >= n) break; 77 | rdfs(d, k); 78 | } 79 | } 80 | 81 | BitsetSCCExec(const V& _g, const V& _rg) 82 | : n(int(_g.size())), g(_g), rg(_rg) { 83 | unvis.set(); 84 | for (int i = 0; i < n; i++) { 85 | if (unvis[i]) dfs(i); 86 | } 87 | reverse(vs.begin(), vs.end()); 88 | unvis.set(); 89 | id = V(n); 90 | int k = 0; 91 | for (int i : vs) { 92 | if (unvis[i]) { 93 | groups.push_back({}); 94 | rdfs(i, k++); 95 | } 96 | } 97 | } 98 | }; 99 | 100 | template 101 | SCC get_bitset_scc(const V>& g, const V>& rg) { 102 | return BitsetSCCExec(g, rg); 103 | } 104 | -------------------------------------------------------------------------------- /src/graph/treedecomp.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "base.hpp" 4 | #include "graph/primitive.hpp" 5 | #include "datastructure/hashset.hpp" 6 | #include "datastructure/hashmap.hpp" 7 | #include "datastructure/simplequeue.hpp" 8 | 9 | struct TreeDecomp { 10 | VV tr; 11 | VV bags; 12 | }; 13 | 14 | 15 | template 16 | TreeDecomp decomp_width2(VV _g) { 17 | int n = int(_g.size()); 18 | assert(n); 19 | 20 | V> g(n); 21 | for (int i = 0; i < n; i++) { 22 | for (auto e : _g[i]) { 23 | int j = e.to; 24 | g[i].insert(j); 25 | } 26 | } 27 | 28 | V deg(n); 29 | V alive(n, true); 30 | SimpleQueue que; 31 | for (int i = 0; i < n; i++) { 32 | deg[i] = int(g[i].size()); 33 | que.push(i); 34 | } 35 | 36 | struct Event { 37 | int deg; 38 | int a, b, c; 39 | }; 40 | V events; 41 | 42 | V nears; 43 | auto remove = [&](int p) { 44 | assert(alive[p]); 45 | alive[p] = false; 46 | for (int i: nears) { 47 | assert(alive[i]); 48 | g[i].erase(p); 49 | deg[i]--; 50 | que.push(i); 51 | } 52 | }; 53 | while (que.size()) { 54 | int p = que.front(); 55 | que.pop(); 56 | int d = deg[p]; 57 | if (!alive[p] || d >= 3) continue; 58 | nears = g[p].to_vec(); 59 | assert(int(nears.size()) == d); 60 | if (d == 0) { 61 | events.push_back({0, p, -1, -1}); 62 | } 63 | if (d == 1) { 64 | events.push_back({1, p, nears[0], -1}); 65 | } 66 | if (d == 2) { 67 | int u = nears[0]; 68 | int v = nears[1]; 69 | events.push_back({2, p, u, v}); 70 | g[u].insert(v); 71 | g[v].insert(u); 72 | deg[u] = int(g[u].size()); 73 | deg[v] = int(g[v].size()); 74 | } 75 | remove(p); 76 | } 77 | 78 | for (int i = 0; i < n; i++) { 79 | if (alive[i]) { 80 | return TreeDecomp{}; 81 | } 82 | } 83 | 84 | TreeDecomp td; 85 | V par; 86 | V node_pos(n, -1); 87 | HashMap, int> edge_pos; 88 | reverse(events.begin(), events.end()); 89 | for (auto event : events) { 90 | int id = int(td.bags.size()); 91 | if (event.deg == 0) { 92 | td.bags.push_back({event.a}); 93 | par.push_back(id - 1); 94 | } 95 | if (event.deg == 1) { 96 | td.bags.push_back({event.a, event.b}); 97 | par.push_back(node_pos[event.b]); 98 | } 99 | if (event.deg == 2) { 100 | td.bags.push_back({event.a, event.b, event.c}); 101 | par.push_back(edge_pos.get(minmax(event.b, event.c))); 102 | } 103 | for (int x : td.bags.back()) { 104 | node_pos[x] = id; 105 | } 106 | for (int x : td.bags.back()) { 107 | for (int y : td.bags.back()) { 108 | if (x < y) edge_pos.set({x, y}, id); 109 | } 110 | } 111 | } 112 | int K = int(td.bags.size()); 113 | td.tr = VV(K); 114 | for (int i = 1; i < K; i++) { 115 | td.tr[par[i]].push_back({i}); 116 | td.tr[i].push_back({par[i]}); 117 | } 118 | return td; 119 | } 120 | -------------------------------------------------------------------------------- /src/graph/twosat.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "graph/scc.hpp" 3 | 4 | struct TwoSat { 5 | V res; 6 | 7 | struct Edge { int to; }; 8 | VV g; 9 | 10 | //(a == a_exp) || (b == b_exp) 11 | void add_cond(int a, bool a_exp, int b, bool b_exp) { 12 | g[2 * a + (a_exp ? 0 : 1)].push_back(Edge{2 * b + (b_exp ? 1 : 0)}); 13 | g[2 * b + (b_exp ? 0 : 1)].push_back(Edge{2 * a + (a_exp ? 1 : 0)}); 14 | } 15 | bool exec() { 16 | int n = int(res.size()); 17 | auto s = get_scc(g); 18 | for (int i = 0; i < n; i++) { 19 | if (s.id[2 * i] == s.id[2 * i + 1]) return false; 20 | res[i] = s.id[2 * i] < s.id[2 * i + 1]; 21 | } 22 | return true; 23 | } 24 | TwoSat() {} 25 | TwoSat(int n) { 26 | g = VV(2 * n); 27 | res = V(n); 28 | } 29 | }; 30 | -------------------------------------------------------------------------------- /src/math/comb.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "base.hpp" 4 | 5 | template 6 | V powTable(int n, Mint x) { 7 | V table(n + 1); 8 | table[0] = Mint(1); 9 | for (int i = 1; i <= n; i++) { 10 | table[i] = table[i - 1] * x; 11 | } 12 | return table; 13 | } 14 | 15 | template 16 | struct Comb { 17 | int max_n; 18 | V fact, ifact; 19 | Comb() {} 20 | Comb(int n) : max_n(n) { 21 | fact = ifact = V(n + 1); 22 | fact[0] = Mint(1); 23 | for (int i = 1; i <= n; i++) fact[i] = fact[i - 1] * i; 24 | ifact[n] = fact[n].inv(); 25 | for (int i = n; i >= 1; i--) ifact[i - 1] = ifact[i] * i; 26 | } 27 | 28 | Mint C(int n, int k) { 29 | if (n < k || n < 0) return Mint(0); 30 | assert(0 <= k && k <= n && n <= max_n); 31 | return fact[n] * ifact[k] * ifact[n - k]; 32 | } 33 | 34 | // n個の区別出来ないボールをk個の箱に入れる入れ方 35 | Mint H(int n, int k) { 36 | if (n == 0 && k == 0) return Mint(1); 37 | return C(n + k - 1, n); 38 | } 39 | }; 40 | -------------------------------------------------------------------------------- /src/math/dynamicmodint.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../bitop.hpp" 4 | 5 | 6 | struct DynamicModInt { 7 | using M = DynamicModInt; 8 | 9 | private: 10 | static uint MD; 11 | static ull iMD; 12 | uint v = 0; 13 | 14 | public: 15 | static void set_mod(uint _MD) { 16 | assert(2 <= _MD); 17 | MD = _MD; 18 | iMD = ull(-1) / _MD + 1; 19 | } 20 | DynamicModInt() {} 21 | DynamicModInt(ll _v) { set_v(uint(_v % MD + MD)); } 22 | uint val() const { return v; } 23 | M& set_v(uint _v) { 24 | v = (_v < MD) ? _v : _v - MD; 25 | return *this; 26 | } 27 | explicit operator bool() const { return v != 0; } 28 | M operator-() const { return M() - *this; } 29 | M operator+(const M& r) const { return M().set_v(v + r.v); } 30 | M operator-(const M& r) const { return M().set_v(v + MD - r.v); } 31 | /* 32 | u32 fact_fast(u32 n, u32 mod) { 33 | u64 imod = u64(-1) / mod + 1; // ceil((1<<64) / mod); 34 | auto mul_mod = [&](u32 a, u32 b) { 35 | u64 c = u64(a) * b; 36 | u64 d = (__uint128_t(c) * imod) >> 64; 37 | u64 e = (c - d * mod + mod); 38 | //return e; 39 | return (e < mod) ? e : e - mod; 40 | }; 41 | u32 ret = 1; 42 | for (int i = 1; i <= n; ++i) ret = mul_mod(ret, i); 43 | return ret; 44 | } 45 | */ 46 | M operator*(const M& r) const { 47 | ull c = ull(v) * r.v; 48 | ull d = (__uint128_t(c) * iMD) >> 64; 49 | return M().set_v(uint(c - d * MD + MD)); 50 | } 51 | M operator/(const M& r) const { return *this * r.inv(); } 52 | M& operator+=(const M& r) { return *this = *this + r; } 53 | M& operator-=(const M& r) { return *this = *this - r; } 54 | M& operator*=(const M& r) { return *this = *this * r; } 55 | M& operator/=(const M& r) { return *this = *this / r; } 56 | bool operator==(const M& r) const { return v == r.v; } 57 | M pow(ll n) const { 58 | M x = *this, r = 1; 59 | while (n) { 60 | if (n & 1) r *= x; 61 | x *= x; 62 | n >>= 1; 63 | } 64 | return r; 65 | } 66 | M inv() const { 67 | pair p = {MD, 0}, q = {v, 1}; 68 | while (q.first) { 69 | uint t = p.first / q.first; 70 | p.first -= t * q.first; 71 | p.second -= t * q.second; 72 | swap(p, q); 73 | } 74 | return M(p.second); 75 | } 76 | friend ostream& operator<<(ostream& os, const M& r) { return os << r.v; } 77 | }; 78 | uint DynamicModInt::MD; 79 | ull DynamicModInt::iMD; 80 | -------------------------------------------------------------------------------- /src/math/fft.hpp: -------------------------------------------------------------------------------- 1 | using D = double; 2 | const D PI = acos(D(-1)); 3 | using Pc = complex; 4 | 5 | void fft(bool type, V& a) { 6 | int n = int(a.size()), s = 0; 7 | while ((1 << s) < n) s++; 8 | assert(1 << s == n); 9 | 10 | static V ep[30]; 11 | if (!ep[s].size()) { 12 | for (int i = 0; i < n; i++) { 13 | ep[s].push_back(polar(1, i * 2 * PI / n)); 14 | } 15 | } 16 | V b(n); 17 | for (int i = 1; i <= s; i++) { 18 | int w = 1 << (s - i); 19 | for (int y = 0; y < n / 2; y += w) { 20 | Pc now = ep[s][y]; 21 | if (type) now = conj(now); 22 | for (int x = 0; x < w; x++) { 23 | auto l = a[y << 1 | x]; 24 | auto u = now, v = a[y << 1 | x | w]; 25 | auto r = Pc(u.real() * v.real() - u.imag() * v.imag(), 26 | u.real() * v.imag() + u.imag() * v.real()); 27 | b[y | x] = l + r; 28 | b[y | x | n >> 1] = l - r; 29 | } 30 | } 31 | swap(a, b); 32 | } 33 | } 34 | 35 | V multiply(const V& a, const V& b) { 36 | int A = int(a.size()), B = int(b.size()); 37 | if (!A || !B) return {}; 38 | int lg = 0; 39 | while ((1 << lg) < A + B - 1) lg++; 40 | int N = 1 << lg; 41 | V ac(N), bc(N); 42 | for (int i = 0; i < A; i++) ac[i] = a[i]; 43 | for (int i = 0; i < B; i++) bc[i] = b[i]; 44 | fft(false, ac); 45 | fft(false, bc); 46 | for (int i = 0; i < N; i++) { 47 | ac[i] *= bc[i]; 48 | } 49 | fft(true, ac); 50 | V c(A + B - 1); 51 | for (int i = 0; i < A + B - 1; i++) { 52 | c[i] = ac[i] / D(N); 53 | } 54 | return c; 55 | } 56 | 57 | V multiply(const V& a, const V& b) { 58 | int A = int(a.size()), B = int(b.size()); 59 | if (!A || !B) return {}; 60 | int lg = 0; 61 | while ((1 << lg) < A + B - 1) lg++; 62 | int N = 1 << lg; 63 | V d(N); 64 | for (int i = 0; i < N; i++) d[i] = Pc(i < A ? a[i] : 0, i < B ? b[i] : 0); 65 | fft(false, d); 66 | for (int i = 0; i < N / 2 + 1; i++) { 67 | auto j = i ? (N - i) : 0; 68 | Pc x = Pc(d[i].real() + d[j].real(), d[i].imag() - d[j].imag()); 69 | Pc y = Pc(d[i].imag() + d[j].imag(), -d[i].real() + d[j].real()); 70 | d[i] = x * y / D(4); 71 | if (i != j) d[j] = conj(d[i]); 72 | } 73 | fft(true, d); 74 | V c(A + B - 1); 75 | for (int i = 0; i < A + B - 1; i++) { 76 | c[i] = d[i].real() / N; 77 | } 78 | return c; 79 | } 80 | 81 | template 82 | V multiply(const V& a, const V& b) { 83 | int A = int(a.size()), B = int(b.size()); 84 | if (!A || !B) return {}; 85 | int lg = 0; 86 | while ((1 << lg) < A + B - 1) lg++; 87 | int N = 1 << lg; 88 | 89 | VV x(K, V(N)), y(K, V(N)); 90 | for (int ph = 0; ph < K; ph++) { 91 | V z(N); 92 | for (int i = 0; i < N; i++) { 93 | D nx = 0, ny = 0; 94 | if (i < A) nx = (a[i].v >> (ph * SHIFT)) & ((1 << SHIFT) - 1); 95 | if (i < B) ny = (b[i].v >> (ph * SHIFT)) & ((1 << SHIFT) - 1); 96 | z[i] = Pc(nx, ny); 97 | } 98 | fft(false, z); 99 | for (int i = 0; i < N; i++) { 100 | z[i] *= 0.5; 101 | } 102 | for (int i = 0; i < N; i++) { 103 | int j = (i) ? N - i : 0; 104 | x[ph][i] = Pc(z[i].real() + z[j].real(), z[i].imag() - z[j].imag()); 105 | y[ph][i] = 106 | Pc(z[i].imag() + z[j].imag(), -z[i].real() + z[j].real()); 107 | } 108 | } 109 | VV z(K, V(N)); 110 | for (int xp = 0; xp < K; xp++) { 111 | for (int yp = 0; yp < K; yp++) { 112 | int zp = (xp + yp) % K; 113 | for (int i = 0; i < N; i++) { 114 | if (xp + yp < K) { 115 | z[zp][i] += x[xp][i] * y[yp][i]; 116 | } else { 117 | z[zp][i] += x[xp][i] * y[yp][i] * Pc(0, 1); 118 | } 119 | } 120 | } 121 | } 122 | for (int ph = 0; ph < K; ph++) { 123 | fft(true, z[ph]); 124 | } 125 | V c(A + B - 1); 126 | Mint base = 1; 127 | for (int ph = 0; ph < 2 * K - 1; ph++) { 128 | for (int i = 0; i < A + B - 1; i++) { 129 | if (ph < K) { 130 | c[i] += Mint(ll(round(z[ph][i].real() / N))) * base; 131 | } else { 132 | c[i] += Mint(ll(round(z[ph - K][i].imag() / N))) * base; 133 | } 134 | } 135 | base *= 1 << SHIFT; 136 | } 137 | return c; 138 | } 139 | -------------------------------------------------------------------------------- /src/math/frac.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "math/primitive.hpp" 4 | 5 | 6 | template struct Frac { 7 | I a, b; // a / b 8 | Frac(I _a = 0) : a(_a), b(1) {} 9 | Frac(I _a, I _b) { 10 | I g = gcd(_a, _b); 11 | if (_b < 0) g = -g; 12 | a = _a / g; 13 | b = _b / g; 14 | } 15 | Frac operator-() const { 16 | Frac f; 17 | f.a = -a; 18 | f.b = b; 19 | return f; 20 | } 21 | Frac operator+(const Frac& r) const { return {r.b * a + b * r.a, b * r.b}; } 22 | Frac operator-(const Frac& r) const { return *this + (-r); } 23 | Frac operator*(const Frac& r) const { return {a * r.a, b * r.b}; } 24 | Frac operator/(const Frac& r) const { return {a * r.b, b * r.a}; } 25 | Frac& operator+=(const Frac& r) { return *this = *this + r; } 26 | Frac& operator-=(const Frac& r) { return *this = *this - r; } 27 | Frac& operator*=(const Frac& r) { return *this = *this * r; } 28 | Frac& operator/=(const Frac& r) { return *this = *this / r; } 29 | bool operator<(const Frac& r) const { return a * r.b < b * r.a; } 30 | bool operator>(const Frac& r) const { return r < *this; } 31 | bool operator<=(const Frac& r) const { return !(r < *this); } 32 | bool operator>=(const Frac& r) const { return !(*this < r); } 33 | bool operator==(const Frac& r) const { 34 | return !(*this < r) && !(r < *this); 35 | } 36 | bool operator!=(const Frac& r) const { return !(*this == r); } 37 | 38 | static Frac rec(Frac x, Frac y, Frac l, Frac r) { 39 | auto flip = [&](Frac& f) { f = Frac(1) - f; }; 40 | auto cross = [&](const Frac& f, const Frac& g) { 41 | return f.a * g.b - f.b * g.a; 42 | }; 43 | Frac m = {l.a + r.a, l.b + r.b}; 44 | if (x < m && m < y) return m; 45 | bool s = !(x < m); 46 | if (s) { 47 | flip(l); 48 | flip(r); 49 | flip(m); 50 | flip(x); 51 | flip(y); 52 | swap(l, r); 53 | swap(x, y); 54 | } 55 | I k = cross(r, y) / cross(y, l) + 1; 56 | Frac p = {k * l.a + r.a, k * l.b + r.b}; 57 | if (x < p) { 58 | if (s) flip(p); 59 | return p; 60 | } 61 | Frac q = rec(x, y, p, {(k - 1) * l.a + r.a, (k - 1) * l.b + r.b}); 62 | if (s) flip(q); 63 | return q; 64 | } 65 | static Frac in_bet(Frac x, Frac y) { 66 | if (y < x) swap(x, y); 67 | Frac ret; 68 | I num = x.a >= 0 ? x.a / x.b : -((x.b - 1 - x.a) / x.b); 69 | x.a -= x.b * num; 70 | y.a -= y.b * num; 71 | if (Frac{1, 1} < y) 72 | ret = Frac{1, 1}; 73 | else 74 | ret = rec(x, y, Frac{0, 1}, Frac{1, 1}); 75 | ret.a += ret.b * num; 76 | return ret; 77 | } 78 | }; 79 | -------------------------------------------------------------------------------- /src/math/modint.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | template struct ModInt { 4 | using M = ModInt; 5 | static constexpr uint get_mod() { return MD; } 6 | const static M G; 7 | uint v; 8 | ModInt(ll _v = 0) { set_v(uint(_v % MD + MD)); } 9 | M& set_v(uint _v) { 10 | v = (_v < MD) ? _v : _v - MD; 11 | return *this; 12 | } 13 | explicit operator bool() const { return v != 0; } 14 | M operator-() const { return M() - *this; } 15 | M operator+(const M& r) const { return M().set_v(v + r.v); } 16 | M operator-(const M& r) const { return M().set_v(v + MD - r.v); } 17 | M operator*(const M& r) const { return M().set_v(uint(ull(v) * r.v % MD)); } 18 | M operator/(const M& r) const { return *this * r.inv(); } 19 | M& operator+=(const M& r) { return *this = *this + r; } 20 | M& operator-=(const M& r) { return *this = *this - r; } 21 | M& operator*=(const M& r) { return *this = *this * r; } 22 | M& operator/=(const M& r) { return *this = *this / r; } 23 | bool operator==(const M& r) const { return v == r.v; } 24 | M pow(ll n) const { 25 | M x = *this, r = 1; 26 | while (n) { 27 | if (n & 1) r *= x; 28 | x *= x; 29 | n >>= 1; 30 | } 31 | return r; 32 | } 33 | M inv() const { return pow(MD - 2); } 34 | friend ostream& operator<<(ostream& os, const M& r) { return os << r.v; } 35 | }; 36 | // using Mint = ModInt<998244353>; 37 | // template<> const Mint Mint::G = Mint(3); 38 | -------------------------------------------------------------------------------- /src/math/modint61.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "base.hpp" 4 | 5 | // ModInt of 2^61 - 1 6 | struct ModInt61 { 7 | static constexpr ull MD = (1ULL << 61) - 1; 8 | using M = ModInt61; 9 | static constexpr ull get_mod() { return MD; } 10 | const static M G; 11 | ull v; 12 | ModInt61(ll _v = 0) { set_v(_v % MD + MD); } 13 | M& set_v(ull _v) { 14 | v = (_v < MD) ? _v : _v - MD; 15 | return *this; 16 | } 17 | explicit operator bool() const { return v != 0; } 18 | M operator-() const { return M() - *this; } 19 | M operator+(const M& r) const { return M().set_v(v + r.v); } 20 | M operator-(const M& r) const { return M().set_v(v + MD - r.v); } 21 | M operator*(const M& r) const { 22 | __uint128_t z = __uint128_t(v) * r.v; 23 | return M().set_v(ull((z & ((1ULL << 61) - 1)) + (z >> 61))); 24 | } 25 | M operator/(const M& r) const { return *this * r.inv(); } 26 | M& operator+=(const M& r) { return *this = *this + r; } 27 | M& operator-=(const M& r) { return *this = *this - r; } 28 | M& operator*=(const M& r) { return *this = *this * r; } 29 | M& operator/=(const M& r) { return *this = *this / r; } 30 | bool operator==(const M& r) const { return v == r.v; } 31 | M pow(ll n) const { 32 | M x = *this, r = 1; 33 | while (n) { 34 | if (n & 1) r *= x; 35 | x *= x; 36 | n >>= 1; 37 | } 38 | return r; 39 | } 40 | M inv() const { return pow(MD - 2); } 41 | friend ostream& operator<<(ostream& os, const M& r) { return os << r.v; } 42 | }; 43 | -------------------------------------------------------------------------------- /src/math/nimber.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "base.hpp" 4 | 5 | struct Nimber64; 6 | Nimber64 mul_naive(Nimber64 l, Nimber64 r); 7 | struct Nimber64 { 8 | const static V factor; 9 | const static array, 256> small; 10 | const static array, 8>, 8> precalc; 11 | ull v; 12 | Nimber64() : v(0) {} 13 | Nimber64(ull _v) : v(_v) {} 14 | const Nimber64 operator+(Nimber64 r) const { return v ^ r.v; } 15 | const Nimber64 operator*(Nimber64 r) const { 16 | Nimber64 ans; 17 | for (int i = 0; i < 8; i++) { 18 | for (int j = 0; j < 8; j++) { 19 | ull x = (v >> (8 * i)) % 256; 20 | ull y = (r.v >> (8 * j)) % 256; 21 | ans += precalc[i][j][small[x][y]]; 22 | } 23 | } 24 | return ans; 25 | } 26 | bool operator==(Nimber64 r) const { return v == r.v; } 27 | Nimber64& operator+=(Nimber64 r) { return *this = *this + r; } 28 | Nimber64& operator*=(Nimber64 r) { return *this = *this * r; } 29 | 30 | Nimber64 pow(ull n) const { 31 | Nimber64 x = *this, r = 1; 32 | while (n) { 33 | if (n & 1) r = r * x; 34 | x = x * x; 35 | n >>= 1; 36 | } 37 | return r; 38 | } 39 | 40 | ull discrete_logarithm(Nimber64 y) { 41 | ull rem = 0, mod = 1; 42 | for (ull p : factor) { 43 | ull STEP = 1; 44 | while (4 * STEP * STEP < p) STEP *= 2; 45 | auto inside = [&](Nimber64 x, Nimber64 z) { 46 | unordered_map mp; 47 | Nimber64 big = 1; // x^m 48 | for (int i = 0; i < int(STEP); i++) { 49 | mp[z.v] = i; 50 | z *= x; 51 | big *= x; 52 | } 53 | Nimber64 now = 1; 54 | for (int step = 0; step < int(p + 10); step += STEP) { 55 | now *= big; 56 | // check [step + 1, step + STEP] 57 | if (mp.find(now.v) != mp.end()) { 58 | return (step + STEP) - mp[now.v]; 59 | } 60 | } 61 | return ull(-1); 62 | }; 63 | 64 | ull q = ull(-1) / p; 65 | ull res = inside((*this).pow(q), y.pow(q)); 66 | if (res == ull(-1)) { 67 | return ull(-1); 68 | } 69 | res %= p; 70 | // mod p = v 71 | if (mod == 1) { 72 | rem = res; 73 | mod = p; 74 | } else { 75 | while (rem % p != res) rem += mod; 76 | mod *= p; 77 | } 78 | } 79 | return rem; 80 | } 81 | 82 | bool is_primitive_root() const { 83 | for (ull p : factor) { 84 | if ((*this).pow(ull(-1) / p).v == 1) return false; 85 | } 86 | return true; 87 | } 88 | }; 89 | const V Nimber64::factor = { 90 | 6700417, 65537, 641, 257, 17, 5, 3, 91 | }; 92 | 93 | Nimber64 mul_naive(Nimber64 l, Nimber64 r) { 94 | ull a = l.v, b = r.v; 95 | if (a < b) swap(a, b); 96 | if (b == 0) return 0; 97 | if (b == 1) return a; 98 | int p = 32; 99 | while (max(a, b) < (1ULL << p)) p /= 2; 100 | ull power = 1ULL << p; 101 | if (a >= power && b >= power) { 102 | Nimber64 ans; 103 | ans += mul_naive(a % power, b % power); 104 | ans += mul_naive(a / power, b % power).v * power; 105 | ans += mul_naive(a % power, b / power).v * power; 106 | auto x = mul_naive(a / power, b / power); 107 | ans += x.v * power; 108 | ans += mul_naive(x.v, power / 2); 109 | return ans; 110 | } else { 111 | return Nimber64(mul_naive(a / power, b).v * power) + 112 | mul_naive(a % power, b); 113 | } 114 | }; 115 | 116 | const array, 256> Nimber64::small = []() { 117 | array, 256> small; 118 | for (int i = 0; i < 256; i++) { 119 | for (int j = 0; j < 256; j++) { 120 | small[i][j] = (unsigned char)(mul_naive(i, j).v); 121 | } 122 | } 123 | return small; 124 | }(); 125 | 126 | const array, 8>, 8> Nimber64::precalc = []() { 127 | array, 8>, 8> precalc; 128 | for (int i = 0; i < 8; i++) { 129 | for (int j = 0; j < 8; j++) { 130 | for (int k = 0; k < 256; k++) { 131 | precalc[i][j][k] = 132 | mul_naive(mul_naive(1ULL << (8 * i), 1ULL << (8 * j)), k); 133 | } 134 | } 135 | } 136 | return precalc; 137 | }(); 138 | -------------------------------------------------------------------------------- /src/math/prime.hpp: -------------------------------------------------------------------------------- 1 | bool is_prime(ll n) { 2 | if (n <= 1) return false; 3 | if (n == 2) return true; 4 | if (n % 2 == 0) return false; 5 | ll d = n - 1; 6 | while (d % 2 == 0) d /= 2; 7 | for (ll a : {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37}) { 8 | if (n <= a) break; 9 | ll t = d; 10 | ll y = pow_mod<__int128_t>(a, t, n); // over 11 | while (t != n - 1 && y != 1 && y != n - 1) { 12 | y = __int128_t(y) * y % n; // flow 13 | t <<= 1; 14 | } 15 | if (y != n - 1 && t % 2 == 0) { 16 | return false; 17 | } 18 | } 19 | return true; 20 | } 21 | 22 | ll pollard_single(ll n) { 23 | auto f = [&](ll x) { return (__int128_t(x) * x + 1) % n; }; 24 | if (is_prime(n)) return n; 25 | if (n % 2 == 0) return 2; 26 | ll st = 0; 27 | while (true) { 28 | st++; 29 | ll x = st, y = f(x); 30 | while (true) { 31 | ll p = gcd((y - x + n), n); 32 | if (p == 0 || p == n) break; 33 | if (p != 1) return p; 34 | x = f(x); 35 | y = f(f(y)); 36 | } 37 | } 38 | } 39 | 40 | V pollard(ll n) { 41 | if (n == 1) return {}; 42 | ll x = pollard_single(n); 43 | if (x == n) return {x}; 44 | V le = pollard(x); 45 | V ri = pollard(n / x); 46 | le.insert(le.end(), ri.begin(), ri.end()); 47 | return le; 48 | } 49 | 50 | ll primitive_root(ll p) { 51 | auto v = pollard(p - 1); 52 | while (true) { 53 | ll g = global_gen.uniform(1LL, p - 1); //[1, p-1] 54 | bool ok = true; 55 | for (auto d : v) { 56 | ll f = (p - 1) / d; 57 | if (pow_mod<__int128_t>(g, f, p) == 1) { 58 | ok = false; 59 | break; 60 | } 61 | } 62 | if (ok) return g; 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/math/primitive.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "bitop.hpp" 4 | 5 | //binary gcd 6 | ll gcd(ll _a, ll _b) { 7 | ull a = abs(_a), b = abs(_b); 8 | if (a == 0) return b; 9 | if (b == 0) return a; 10 | int shift = bsf(a|b); 11 | a >>= bsf(a); 12 | do { 13 | b >>= bsf(b); 14 | if (a > b) swap(a, b); 15 | b -= a; 16 | } while (b); 17 | return (a << shift); 18 | } 19 | 20 | /// g:gcd(a, b), ax+by=g 21 | struct EG { ll g, x, y; }; 22 | EG ext_gcd(ll a, ll b) { 23 | if (b == 0) { 24 | if (a >= 0) return EG{a, 1, 0}; 25 | else return EG{-a, -1, 0}; 26 | } else { 27 | auto e = ext_gcd(b, a % b); 28 | return EG{e.g, e.y, e.x - a / b * e.y}; 29 | } 30 | } 31 | 32 | 33 | ll inv_mod(ll x, ll md) { 34 | auto z = ext_gcd(x, md).x; 35 | return (z % md + md) % md; 36 | } 37 | 38 | template 39 | T pow_mod(T x, U n, T md) { 40 | T r = 1 % md; 41 | x %= md; 42 | while (n) { 43 | if (n & 1) r = (r * x) % md; 44 | x = (x * x) % md; 45 | n >>= 1; 46 | } 47 | return r; 48 | } 49 | 50 | // (rem, mod) 51 | pair crt(const V& b, const V& c) { 52 | int n = int(b.size()); 53 | ll r = 0, m = 1; 54 | for (int i = 0; i < n; i++) { 55 | auto eg = ext_gcd(m, c[i]); 56 | ll g = eg.g, im = eg.x; 57 | if ((b[i] - r) % g) return {0, -1}; 58 | ll tmp = (b[i] - r) / g * im % (c[i] / g); 59 | r += m * tmp; 60 | m *= c[i] / g; 61 | } 62 | return {(r % m + m) % m, m}; 63 | } 64 | -------------------------------------------------------------------------------- /src/math/qr.hpp: -------------------------------------------------------------------------------- 1 | template 2 | struct QR { 3 | Matrix q, r; 4 | static QR decomp(const Matrix &x, T eps) { 5 | int N = x.N, M = x.M; 6 | assert(N <= M); 7 | Matrix A = x; 8 | Matrix B(N, N); 9 | for (int i = 0; i < N; i++) { 10 | B[i][i] = 1; 11 | } 12 | for (int i = 0; i < N; i++) { 13 | for (int j = i+1; j < N; j++) { 14 | T r = hypot(A[i][i], A[j][i]); 15 | if (abs(r) <= eps) continue; 16 | T c = A[i][i]/r, s = A[j][i]/r; 17 | for (int k = i; k < M; k++) { 18 | tie(A[i][k], A[j][k]) = 19 | make_pair(c*A[i][k]+s*A[j][k], -s*A[i][k]+c*A[j][k]); 20 | } 21 | for (int k = 0; k < N; k++) { 22 | tie(B[i][k], B[j][k]) = 23 | make_pair(c*B[i][k]+s*B[j][k], -s*B[i][k]+c*B[j][k]); 24 | } 25 | if (A[i][i] == 0) { 26 | // not full rank 27 | assert(false); 28 | } 29 | } 30 | } 31 | return QR{B, A}; 32 | } 33 | static Matrix solve(QR qr, Matrix ar) { 34 | int N = qr.q.N, M = qr.r.M; 35 | assert(ar.N == M && ar.M == 1); 36 | auto b = qr.q*ar; 37 | Matrix ans(M, 1); 38 | for (int i = M-1; i >= 0; i--) { 39 | ans[i][0] = b[i][0]; 40 | for (int j = i+1; j < b.N; j++) { 41 | ans[i][0] -= qr.r[i][j] * ans[j][0]; 42 | } 43 | ans[i][0] /= qr.r[i][i]; 44 | } 45 | return ans; 46 | } 47 | }; 48 | -------------------------------------------------------------------------------- /src/string/ahocorasick.hpp: -------------------------------------------------------------------------------- 1 | struct ACTrie { 2 | using NP = ACTrie*; 3 | V acc; 4 | map next; 5 | NP fail = nullptr, dnx = nullptr; 6 | 7 | private: 8 | void add(const string& s, int id, int p = 0) { 9 | if (p == int(s.size())) { 10 | acc.push_back(id); 11 | return; 12 | } 13 | if (next[s[p]] == nullptr) { 14 | next[s[p]] = new ACTrie(); 15 | } 16 | next[s[p]]->add(s, id, p + 1); 17 | } 18 | template NP count(OP op, int p) { 19 | if (fail == nullptr) return this; 20 | for (int id : acc) { 21 | op(id, p); 22 | } 23 | if (dnx) { 24 | dnx->count(op, p); 25 | } else { 26 | dnx = fail->count(op, p); 27 | } 28 | return acc.size() ? this : dnx; 29 | } 30 | 31 | public: 32 | // パターンにマッチするたびにop(string ID, 発見位置の終端)を呼び出す 33 | // 終端が同じで複数マッチする文字列が存在する場合,長い順に呼び出される 34 | // s = "abaaba", pattern = {"ab", "ba"} なら 35 | // op(0, 2), op(1, 3), op(0, 5), op(1, 6) 36 | template void match(const string& s, OP op, int p = 0) { 37 | if (p == int(s.size())) return; 38 | if (next[s[p]]) { 39 | next[s[p]]->count(op, p + 1); 40 | next[s[p]]->match(s, op, p + 1); 41 | } else { 42 | if (!fail) 43 | match(s, op, p + 1); // root 44 | else 45 | fail->match(s, op, p); // other 46 | } 47 | } 48 | static NP make(V v) { 49 | NP tr = new ACTrie(); 50 | for (int i = 0; i < int(v.size()); i++) { 51 | tr->add(v[i], i); 52 | } 53 | queue q; 54 | q.push(tr); 55 | tr->fail = nullptr; 56 | while (!q.empty()) { 57 | NP ntr = q.front(); 58 | q.pop(); 59 | for (auto p : ntr->next) { 60 | int i = p.first; 61 | NP fail = ntr->fail; 62 | while (fail && !fail->next.count(i)) { 63 | fail = fail->fail; 64 | } 65 | ntr->next[i]->fail = (fail == nullptr) ? tr : fail->next[i]; 66 | q.push(ntr->next[i]); 67 | } 68 | } 69 | return tr; 70 | } 71 | }; 72 | -------------------------------------------------------------------------------- /src/string/manacher.hpp: -------------------------------------------------------------------------------- 1 | template V manacher(const S& s) { 2 | int n = int(s.size()); 3 | V r(n); 4 | if (n == 0) return r; 5 | r[0] = 1; 6 | for (int i = 1, j = 0; i < n; i++) { 7 | int& k = r[i]; 8 | k = (j + r[j] <= i) ? 0 : min(j + r[j] - i, r[2 * j - i]); 9 | while (0 <= i - k && i + k < n && s[i - k] == s[i + k]) k++; 10 | if (j + r[j] < i + r[i]) j = i; 11 | } 12 | return r; 13 | } 14 | 15 | 16 | template V manacher_even(const S& s) { 17 | int n = int(s.size()); 18 | V r(n + 1); 19 | for (int i = 1, j = 0; i < n; i++) { 20 | int& k = r[i]; 21 | k = (j + r[j] <= i) ? 0 : min(j + r[j] - i, r[2 * j - i]); 22 | while (0 <= i - 1 - k && i + k < n && s[i - 1 - k] == s[i + k]) k++; 23 | if (j + r[j] < i + r[i]) j = i; 24 | } 25 | return r; 26 | } 27 | -------------------------------------------------------------------------------- /src/string/mp.hpp: -------------------------------------------------------------------------------- 1 | template V mp(const S& s) { 2 | int n = int(s.size()); 3 | V r(n + 1); 4 | r[0] = -1; 5 | for (int i = 0, j = -1; i < n; i++) { 6 | while (j >= 0 && s[i] != s[j]) j = r[j]; 7 | j++; 8 | r[i + 1] = j; 9 | } 10 | return r; 11 | } 12 | -------------------------------------------------------------------------------- /src/string/onlinez.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct OnlineZ { 4 | string s; 5 | V mp = {-1}, nx; 6 | int j = -1; 7 | V inc(char c) { 8 | // calc nx 9 | s.push_back(c); 10 | if (mp.back() == -1) 11 | nx.push_back(-1); 12 | else 13 | nx.push_back(s[mp.back()] != c ? mp.back() : nx[mp.back()]); 14 | // calc mp 15 | int i = int(s.size()) - 1; 16 | while (j >= 0 && s[i] != s[j]) j = mp[j]; 17 | j++; 18 | mp.push_back(j); 19 | 20 | V res; 21 | int u = nx.back(); 22 | while (u != -1) { 23 | if (s[u] != c) { 24 | res.push_back(int(s.size()) - 1 - u); 25 | u = mp[u]; 26 | } else { 27 | u = nx[u]; 28 | } 29 | } 30 | return res; 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /src/string/rollinghash.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "math/comb.hpp" 4 | #include "math/modint61.hpp" 5 | #include "util/random.hpp" 6 | 7 | struct H { 8 | private: 9 | static ModInt61 B; 10 | static ModInt61 iB; 11 | static V powB, powiB; 12 | 13 | public: 14 | static void init(int n) { 15 | powB = powTable(n, B); 16 | powiB = powTable(n, iB); 17 | } 18 | int le = 0; 19 | ModInt61 h; 20 | H() : le(0), h(0) {} 21 | H(int _le, ModInt61 _h) : le(_le), h(_h) {} 22 | H(int c) : le(1), h(c) {} 23 | // H(l) + H(r) = H(lr) 24 | H operator+(const H& r) const { return H{le + r.le, h + r.h * powB[le]}; } 25 | H& operator+=(const H& r) { return *this = *this + r; } 26 | 27 | bool operator==(const H& r) const { return le == r.le && h == r.h; } 28 | bool operator!=(const H& r) const { return !(*this == r); } 29 | // H(lr).strip_left(H(l)) = H(r) 30 | H strip_left(const H& l) const { 31 | return H{le - l.le, (h - l.h) * powiB[l.le]}; 32 | } 33 | // H(lr).strip_right(H(r)) = H(l) 34 | H strip_right(const H& r) const { 35 | return H{le - r.le, h - r.h * powB[le - r.le]}; 36 | } 37 | }; 38 | ModInt61 H::B = 39 | ModInt61(global_runtime_gen().uniform(0ULL, ModInt61::get_mod() - 1)); 40 | ModInt61 H::iB = H::B.inv(); 41 | V H::powB, H::powiB; 42 | -------------------------------------------------------------------------------- /src/string/run.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "base.hpp" 4 | #include "string/zalgo.hpp" 5 | 6 | template 7 | struct RunExec { 8 | VV> runs; 9 | 10 | int n; 11 | Str a; 12 | 13 | V rev(V l) { 14 | reverse(l.begin(), l.end()); 15 | return l; 16 | } 17 | 18 | V sub_a(int l, int r) { return {a.begin() + l, a.begin() + r}; } 19 | V concat(V l, const V& r) { 20 | l.insert(l.end(), r.begin(), r.end()); 21 | return l; 22 | } 23 | 24 | void run(int l, int r, int f) { 25 | if (l + 1 == r) return; 26 | int md = (l + r + f) / 2; 27 | run(l, md, f); 28 | run(md, r, f); 29 | auto z1 = z_algo(rev(sub_a(l, md))); 30 | auto z2 = z_algo(concat(sub_a(md, r), sub_a(l, r))); 31 | for (int i = md - 1; i >= l; i--) { 32 | int l1 = min(i - l, z1[md - i]); 33 | int l2 = min(r - md, z2[(r - l) - (md - i)]); 34 | int le = i - l1, ri = md + l2, peri = md - i; 35 | if (ri - le >= 2 * peri) runs[md - i].push_back({i - l1, md + l2}); 36 | } 37 | } 38 | 39 | RunExec(Str _a) : a(_a) { 40 | n = int(a.size()); 41 | runs.resize(n / 2 + 1); 42 | reverse(a.begin(), a.end()); 43 | run(0, n, 0); 44 | for (auto& run : runs) { 45 | for (auto& p : run) { 46 | tie(p.first, p.second) = make_pair(n - p.second, n - p.first); 47 | } 48 | } 49 | reverse(a.begin(), a.end()); 50 | run(0, n, 1); 51 | 52 | set> vis; 53 | for (int ph = 1; ph <= n / 2; ph++) { 54 | auto& run = runs[ph]; 55 | sort(run.begin(), run.end(), 56 | [&](pair lhs, pair rhs) { 57 | if (lhs.first != rhs.first) return lhs.first < rhs.first; 58 | return lhs.second > rhs.second; 59 | }); 60 | V> res; 61 | for (auto p : run) { 62 | if (!res.empty() && p.second <= res.back().second) continue; 63 | res.push_back(p); 64 | } 65 | run = res; 66 | res.clear(); 67 | for (auto p : run) { 68 | if (vis.count(p)) continue; 69 | vis.insert(p); 70 | res.push_back(p); 71 | } 72 | run = res; 73 | } 74 | } 75 | }; 76 | -------------------------------------------------------------------------------- /src/string/zalgo.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // s[0..r[i]] == s[i..i+r[i]] 4 | template V z_algo(const S& s) { 5 | int n = int(s.size()); 6 | V r(n + 1); 7 | r[0] = 0; 8 | for (int i = 1, j = 0; i <= n; i++) { 9 | int& k = r[i]; 10 | k = (j + r[j] <= i) ? 0 : min(j + r[j] - i, r[i - j]); 11 | while (i + k < n && s[k] == s[i + k]) k++; 12 | if (j + r[j] < i + r[i]) j = i; 13 | } 14 | r[0] = n; 15 | return r; 16 | } 17 | -------------------------------------------------------------------------------- /src/tree/alltree.hpp: -------------------------------------------------------------------------------- 1 | template struct AllTree { 2 | int n; 3 | const VV& g; 4 | V sm; 5 | VV dp; // tree 6 | void dfs1(int p, int b) { 7 | sm[p] = N(); 8 | for (auto e : g[p]) { 9 | int d = e.to; 10 | if (d == b) continue; 11 | dfs1(d, p); 12 | sm[p] = sm[p] + sm[d].to_subs(p, e); 13 | } 14 | sm[p] = sm[p].join(p); 15 | } 16 | void dfs2(int p, int b, N top) { 17 | int deg = int(g[p].size()); 18 | dp[p] = V(deg + 1); 19 | dp[p][0] = N(); 20 | for (int i = 0; i < deg; i++) { 21 | int d = g[p][i].to; 22 | dp[p][i + 1] = 23 | dp[p][i] + (d == b ? top : sm[d]).to_subs(p, g[p][i]); 24 | } 25 | N rnode = N(); 26 | dp[p].back() = dp[p].back().join(p); 27 | for (int i = deg - 1; i >= 0; i--) { 28 | dp[p][i] = (dp[p][i] + rnode).join(p); 29 | int d = g[p][i].to; 30 | if (d != b) dfs2(d, p, dp[p][i]); 31 | rnode = rnode + (d == b ? top : sm[d]).to_subs(p, g[p][i]); 32 | } 33 | } 34 | AllTree(const VV& _g) : n(int(_g.size())), g(_g), sm(n), dp(n) { 35 | dfs1(0, -1); 36 | dfs2(0, -1, N()); 37 | } 38 | }; 39 | 40 | template VV get_all_tree(const VV& g) { 41 | return AllTree(g).dp; 42 | } 43 | 44 | struct Node { 45 | // Educational DP Contest V - Subtree 46 | Mint sm = Mint(1); 47 | template Node to_subs(int, const E&) const { 48 | // tree -> subtrees 49 | return {sm + 1}; 50 | } 51 | Node operator+(const Node& r) const { 52 | // subtrees + subtrees 53 | return {sm * r.sm}; 54 | } 55 | Node join(int) const { 56 | // subtrees -> tree 57 | return *this; 58 | } 59 | }; 60 | 61 | struct Node { 62 | // Diameter of Tree 63 | int rad = 0, dia = 0; // radius(tree), diameter 64 | array rd = {{0, 0}}; // radiuses(subtrees) 65 | template Node to_subs(int, const E& e) const { 66 | // tree -> subtrees 67 | return {-1, dia, {rad + e.dist, 0}}; 68 | } 69 | Node operator+(const Node& r) const { 70 | // subtrees + subtrees 71 | array v = {rd[0], rd[1], r.rd[0], r.rd[1]}; 72 | sort(v.begin(), v.end(), greater<>()); 73 | return {-1, max(dia, r.dia), {v[0], v[1]}}; 74 | } 75 | Node join(int) const { 76 | // subtrees -> tree 77 | return {rd[0], max(dia, rd[0] + rd[1]), {}}; 78 | } 79 | }; 80 | -------------------------------------------------------------------------------- /src/tree/centroid.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct Centroid { 4 | int r; 5 | VV tr; 6 | V par; 7 | }; 8 | 9 | template struct CentroidExec : Centroid { 10 | int n; 11 | const VV& g; 12 | V used; 13 | 14 | using P = pair; 15 | V

info; //(child max, child) 16 | 17 | int dfs(int p, int b) { 18 | int sz = 1; 19 | info[p] = P(0, -1); 20 | for (E e : g[p]) { 21 | int d = e.to; 22 | if (d == b || used[d]) continue; 23 | int csz = dfs(d, p); 24 | sz += csz; 25 | info[p] = max(info[p], P(csz, d)); 26 | } 27 | return sz; 28 | } 29 | int init(int p, int b) { 30 | int sz = dfs(p, -1); 31 | while (info[p].first > sz / 2) p = info[p].second; 32 | par[p] = b; 33 | used[p] = true; 34 | for (E e : g[p]) { 35 | int d = e.to; 36 | if (used[d]) continue; 37 | tr[p].push_back(init(d, p)); 38 | } 39 | return p; 40 | } 41 | CentroidExec(const VV& _g) : n(int(_g.size())), g(_g), used(n), info(n) { 42 | tr = VV(n); 43 | par = V(n); 44 | r = init(0, -1); 45 | } 46 | }; 47 | 48 | template Centroid get_centroid(const VV& g) { 49 | return CentroidExec(g); 50 | } 51 | -------------------------------------------------------------------------------- /src/tree/hl.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | struct HL { 5 | // inside index of HL 6 | struct I { 7 | int i; 8 | }; 9 | V _ord; // int -> I 10 | V _rord; // I -> int 11 | V _big, _small; // I -> I 12 | // optionals 13 | V dps; // node depth(int -> int) 14 | int pc = 0; // path count(optional) 15 | V pid, psz; // path id, size (optional) 16 | V _out; // ouv[i] is end of subtree(I -> I) 17 | HL() {} 18 | HL(size_t n) 19 | : _ord(n), _rord(n), _big(n), _small(n), dps(n), pid(n), _out(n) {} 20 | I ord(int v) const { return v == -1 ? I{-1} : I{_ord[v]}; } 21 | int rord(I i) const { return i.i == -1 ? -1 : _rord[i.i]; } 22 | I par(I i) const { return I{_small[i.i] == i.i ? _big[i.i] : i.i - 1}; } 23 | I subtree_out(int v) const { return I{_out[ord(v).i]}; }; 24 | int par(int v) const { return rord(par(ord(v))); } 25 | int lca(int a, int b) const { 26 | int ai = ord(a).i; 27 | int bi = ord(b).i; 28 | while (ai != bi) { 29 | if (ai > bi) swap(ai, bi); 30 | if (_small[bi] <= ai) 31 | break; 32 | else 33 | bi = _big[bi]; 34 | } 35 | return rord(I{ai}); 36 | } 37 | // aの直前までbから登る、f(I, I)の引数は両閉区間 38 | template void get_path(int a, int b, F f) const { 39 | int ai = ord(a).i; 40 | int bi = ord(b).i; 41 | while (ai < bi) { 42 | if (_small[bi] <= ai) 43 | f(I{ai + 1}, I{bi}); 44 | else 45 | f(I{_small[bi]}, I{bi}); 46 | bi = _big[bi]; 47 | } 48 | } 49 | int to(int a, int b) { // aからbの方向へ1移動する 50 | int ai = ord(a).i; 51 | int bi = ord(b).i; 52 | assert(ai < bi); 53 | while (true) { 54 | if (_small[bi] <= ai) 55 | return rord(I{ai + 1}); 56 | else if (_big[bi] == ai) 57 | return rord(I{_small[bi]}); 58 | bi = _big[bi]; 59 | } 60 | assert(false); 61 | } 62 | int dist(int a, int b) const { 63 | int c = lca(a, b); 64 | return dps[a] + dps[b] - 2 * dps[c]; 65 | } 66 | }; 67 | 68 | template struct HLExec : HL { 69 | const VV& g; 70 | V tch; 71 | int id = 0; 72 | HLExec(const VV& _g, int r) : HL(_g.size()), g(_g), tch(g.size(), -1) { 73 | assert(dfs_sz(r, -1) == int(g.size())); 74 | dfs(r, -1); 75 | init_extra(); 76 | } 77 | void init_extra() { 78 | // ord, rord, big, small以外を使わないなら不要 79 | int n = int(g.size()); 80 | 81 | // dps 82 | dps[rord(I{0})] = 0; 83 | for (int i = 1; i < n; i++) { 84 | dps[rord(I{i})] = dps[rord(par(I{i}))] + 1; 85 | } 86 | 87 | // pid, psz, pc 88 | int l = 0; 89 | while (l < n) { 90 | int r = l + 1; 91 | while (r < n && _small[r] == l) r++; 92 | psz.push_back(r - l); 93 | for (int i = l; i < r; i++) { 94 | pid[i] = pc; 95 | } 96 | l = r; 97 | pc++; 98 | } 99 | 100 | // out 101 | for (int i = n - 1; i >= 0; i--) { 102 | _out[i] = max(_out[i], i + 1); 103 | int p = ord(par(rord(I{i}))).i; 104 | if (p != -1) _out[p] = max(_out[p], _out[i]); 105 | } 106 | } 107 | int dfs_sz(int p, int b) { 108 | int sz = 1, msz = -1; 109 | for (auto e : g[p]) { 110 | if (e.to == b) continue; 111 | int u = dfs_sz(e.to, p); 112 | sz += u; 113 | if (msz < u) tie(tch[p], msz) = make_pair(e.to, u); 114 | } 115 | return sz; 116 | } 117 | void dfs(int p, int b) { 118 | int q = id++, bq = ord(b).i; 119 | _ord[p] = q; 120 | _rord[q] = p; 121 | if (b == -1 || bq != q - 1) { 122 | _small[q] = q; 123 | _big[q] = bq; 124 | } else { 125 | _small[q] = _small[bq]; 126 | _big[q] = _big[bq]; 127 | } 128 | if (tch[p] == -1) return; 129 | dfs(tch[p], p); 130 | for (auto e : g[p]) { 131 | if (e.to == b || e.to == tch[p]) continue; 132 | dfs(e.to, p); 133 | } 134 | } 135 | }; 136 | 137 | template HL get_hl(const VV& g, int r) { return HLExec(g, r); } 138 | -------------------------------------------------------------------------------- /src/tree/lca.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | struct LCA { 4 | int lg; 5 | VV anc; 6 | V dps; 7 | /// lとrの頂点のLCAを求める 8 | int query(int l, int r) { 9 | if (dps[l] < dps[r]) swap(l, r); 10 | int dd = dps[l] - dps[r]; 11 | for (int i = lg - 1; i >= 0; i--) { 12 | if (dd < (1 << i)) continue; 13 | dd -= 1 << i; 14 | l = anc[i][l]; 15 | } 16 | if (l == r) return l; 17 | for (int i = lg - 1; i >= 0; i--) { 18 | if (anc[i][l] == anc[i][r]) continue; 19 | tie(l, r) = tie(anc[i][l], anc[i][r]); 20 | } 21 | return anc[0][l]; 22 | } 23 | int up(int p, int dist) { 24 | for (int i = lg - 1; i >= 0; i--) { 25 | if (dist >= (1 << i)) { 26 | dist -= 1 << i; 27 | p = anc[i][p]; 28 | } 29 | } 30 | return p; 31 | } 32 | int dist(int l, int r) { 33 | int z = query(l, r); 34 | return dps[l] + dps[r] - 2 * dps[z]; 35 | } 36 | }; 37 | 38 | template struct LCAExec : LCA { 39 | const VV& g; 40 | 41 | /// 事前処理を行う rはroot頂点のid 42 | LCAExec(const VV& _g, int r) : g(_g) { 43 | int N = int(g.size()); 44 | lg = 1; 45 | while ((1 << lg) < N) lg++; 46 | anc = VV(lg, V(N, -1)); 47 | dps = V(N); 48 | dfs(r, -1, 0); 49 | for (int i = 1; i < lg; i++) { 50 | for (int j = 0; j < N; j++) { 51 | anc[i][j] = 52 | (anc[i - 1][j] == -1) ? -1 : anc[i - 1][anc[i - 1][j]]; 53 | } 54 | } 55 | } 56 | 57 | void dfs(int p, int b, int now) { 58 | anc[0][p] = b; 59 | dps[p] = now; 60 | for (E e : g[p]) { 61 | if (e.to == b) continue; 62 | dfs(e.to, p, now + 1); 63 | } 64 | } 65 | }; 66 | 67 | template LCA get_lca(const VV& g, int r) { 68 | return LCAExec(g, r); 69 | } 70 | -------------------------------------------------------------------------------- /src/util/fast_io.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | struct Scanner { 6 | int fd = -1; 7 | char line[(1 << 15) + 1]; 8 | size_t st = 0, ed = 0; 9 | void reread() { 10 | memmove(line, line + st, ed - st); 11 | ed -= st; 12 | st = 0; 13 | ed += ::read(fd, line + ed, (1 << 15) - ed); 14 | line[ed] = '\0'; 15 | } 16 | bool succ() { 17 | while (true) { 18 | if (st == ed) { 19 | reread(); 20 | if (st == ed) return false; 21 | } 22 | while (st != ed && isspace(line[st])) st++; 23 | if (st != ed) break; 24 | } 25 | if (ed - st <= 50) { 26 | bool sep = false; 27 | for (size_t i = st; i < ed; i++) { 28 | if (isspace(line[i])) { 29 | sep = true; 30 | break; 31 | } 32 | } 33 | if (!sep) reread(); 34 | } 35 | return true; 36 | } 37 | template ::value, int> = 0> 38 | bool read_single(T& ref) { 39 | if (!succ()) return false; 40 | while (true) { 41 | size_t sz = 0; 42 | while (st + sz < ed && !isspace(line[st + sz])) sz++; 43 | ref.append(line + st, sz); 44 | st += sz; 45 | if (!sz || st != ed) break; 46 | reread(); 47 | } 48 | return true; 49 | } 50 | template ::value, int> = 0> 51 | bool read_single(T& ref) { 52 | if (!succ()) return false; 53 | bool neg = false; 54 | if (line[st] == '-') { 55 | neg = true; 56 | st++; 57 | } 58 | ref = T(0); 59 | while (isdigit(line[st])) { 60 | ref = 10 * ref + (line[st++] & 0xf); 61 | } 62 | if (neg) ref = -ref; 63 | return true; 64 | } 65 | template bool read_single(V& ref) { 66 | for (auto& d : ref) { 67 | if (!read_single(d)) return false; 68 | } 69 | return true; 70 | } 71 | void read() {} 72 | template void read(H& h, T&... t) { 73 | bool f = read_single(h); 74 | assert(f); 75 | read(t...); 76 | } 77 | Scanner(FILE* fp) : fd(fileno(fp)) {} 78 | }; 79 | 80 | struct Printer { 81 | public: 82 | template void write() {} 83 | template 84 | void write(const H& h, const T&... t) { 85 | if (F) write_single(' '); 86 | write_single(h); 87 | write(t...); 88 | } 89 | template void writeln(const T&... t) { 90 | write(t...); 91 | write_single('\n'); 92 | } 93 | 94 | Printer(FILE* _fp) : fp(_fp) {} 95 | ~Printer() { flush(); } 96 | 97 | private: 98 | static constexpr size_t SIZE = 1 << 15; 99 | FILE* fp; 100 | char line[SIZE], small[50]; 101 | size_t pos = 0; 102 | void flush() { 103 | fwrite(line, 1, pos, fp); 104 | pos = 0; 105 | } 106 | void write_single(const char& val) { 107 | if (pos == SIZE) flush(); 108 | line[pos++] = val; 109 | } 110 | template ::value, int> = 0> 111 | void write_single(T val) { 112 | if (pos > (1 << 15) - 50) flush(); 113 | if (val == 0) { 114 | write_single('0'); 115 | return; 116 | } 117 | if (val < 0) { 118 | write_single('-'); 119 | val = -val; // todo min 120 | } 121 | size_t len = 0; 122 | while (val) { 123 | small[len++] = char(0x30 | (val % 10)); 124 | val /= 10; 125 | } 126 | for (size_t i = 0; i < len; i++) { 127 | line[pos + i] = small[len - 1 - i]; 128 | } 129 | pos += len; 130 | } 131 | void write_single(const string& s) { 132 | for (char c : s) write_single(c); 133 | } 134 | void write_single(const char* s) { 135 | size_t len = strlen(s); 136 | for (size_t i = 0; i < len; i++) write_single(s[i]); 137 | } 138 | template void write_single(const V& val) { 139 | auto n = val.size(); 140 | for (size_t i = 0; i < n; i++) { 141 | if (i) write_single(' '); 142 | write_single(val[i]); 143 | } 144 | } 145 | }; 146 | -------------------------------------------------------------------------------- /src/util/hash.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "base.hpp" 4 | #include "util/random.hpp" 5 | 6 | // Reference: Lemire, Daniel., and Owen, Kaser. "Strongly Universal String Hashing Is Fast." 7 | template struct Hasher { 8 | private: 9 | static ull offset; 10 | static array seed; 11 | 12 | template 13 | struct Encoder { 14 | ull now = offset; 15 | Encoder update(uint x) { 16 | return Encoder{now + x * seed[I]}; 17 | } 18 | Encoder update(int x) { 19 | return update(uint(x)); 20 | } 21 | Encoder update(ull x) { 22 | return Encoder{now + uint(x) * seed[I] + (x >> 32) * seed[I + 1]}; 23 | } 24 | Encoder update(ll x) { 25 | return update(ll(x)); 26 | } 27 | uint digest() const { 28 | static_assert(I <= N); 29 | return uint(now >> 32); 30 | } 31 | }; 32 | 33 | public: 34 | static uint hash(uint x) { return Encoder<>{}.update(x).digest(); } 35 | static uint hash(ull x) { return Encoder<>{}.update(x).digest(); } 36 | static uint hash(int x) { return hash(uint(x)); } 37 | static uint hash(ll x) { return hash(ull(x)); } 38 | template static uint hash(const pair& p) { 39 | return Encoder<>{}.update(p.first).update(p.second).digest(); 40 | } 41 | }; 42 | 43 | template 44 | ull Hasher::offset = global_runtime_gen().uniform(0ULL, ull(-1)); 45 | 46 | template 47 | array Hasher::seed = []() { 48 | array seed; 49 | for (uint i = 0; i < N; i++) { 50 | seed[i] = global_runtime_gen().uniform(0ULL, ull(-1)); 51 | } 52 | return seed; 53 | }(); 54 | -------------------------------------------------------------------------------- /src/util/random.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | struct Random { 14 | private: 15 | // Use xoshiro256** 16 | // Refereces: http://xoshiro.di.unimi.it/xoshiro256starstar.c 17 | static uint64_t rotl(const uint64_t x, int k) { 18 | return (x << k) | (x >> (64 - k)); 19 | } 20 | 21 | std::array s; 22 | 23 | uint64_t next() { 24 | const uint64_t result_starstar = rotl(s[1] * 5, 7) * 9; 25 | 26 | const uint64_t t = s[1] << 17; 27 | 28 | s[2] ^= s[0]; 29 | s[3] ^= s[1]; 30 | s[1] ^= s[2]; 31 | s[0] ^= s[3]; 32 | 33 | s[2] ^= t; 34 | 35 | s[3] = rotl(s[3], 45); 36 | 37 | return result_starstar; 38 | } 39 | 40 | // random choice from [0, upper] 41 | uint64_t next(uint64_t upper) { 42 | if (!(upper & (upper + 1))) { 43 | // b = 00..0011..11 44 | return next() & upper; 45 | } 46 | int lg = 63 - __builtin_clzll(upper); 47 | uint64_t mask = (lg == 63) ? ~0ULL : (1ULL << (lg + 1)) - 1; 48 | while (true) { 49 | uint64_t r = next() & mask; 50 | if (r <= upper) return r; 51 | } 52 | } 53 | 54 | public: 55 | Random(uint64_t seed = 0) { 56 | // Use splitmix64 57 | // Reference: http://xoshiro.di.unimi.it/splitmix64.c 58 | for (int i = 0; i < 4; i++) { 59 | uint64_t z = (seed += 0x9e3779b97f4a7c15); 60 | z = (z ^ (z >> 30)) * 0xbf58476d1ce4e5b9; 61 | z = (z ^ (z >> 27)) * 0x94d049bb133111eb; 62 | s[i] = z ^ (z >> 31); 63 | } 64 | } 65 | 66 | // random choice from [lower, upper] 67 | template T uniform(T lower, T upper) { 68 | assert(lower <= upper); 69 | return T(lower + next(uint64_t(upper - lower))); 70 | } 71 | 72 | bool uniform_bool() { return uniform(0, 1) == 1; } 73 | 74 | double uniform01() { 75 | uint64_t v = next(1ULL << 63); 76 | return double(v) / (1ULL << 63); 77 | } 78 | 79 | template std::pair uniform_pair(T lower, T upper) { 80 | assert(upper - lower >= 1); 81 | T a, b; 82 | do { 83 | a = uniform(lower, upper); 84 | b = uniform(lower, upper); 85 | } while (a == b); 86 | if (a > b) std::swap(a, b); 87 | return {a, b}; 88 | } 89 | 90 | // generate random lower string that length = n 91 | std::string lower_string(size_t n) { 92 | std::string res = ""; 93 | for (size_t i = 0; i < n; i++) { 94 | res += uniform('a', 'z'); 95 | } 96 | return res; 97 | } 98 | 99 | // random shuffle 100 | template void shuffle(Iter first, Iter last) { 101 | if (first == last) return; 102 | // Reference and edit: 103 | // cpprefjp - C++日本語リファレンス 104 | // (https://cpprefjp.github.io/reference/algorithm/shuffle.html) 105 | int len = 1; 106 | for (auto it = first + 1; it != last; it++) { 107 | len++; 108 | int j = uniform(0, len - 1); 109 | if (j != len - 1) iter_swap(it, first + j); 110 | } 111 | } 112 | 113 | // generate random permutation that length = n 114 | template std::vector perm(size_t n) { 115 | std::vector idx(n); 116 | std::iota(idx.begin(), idx.end(), T(0)); 117 | shuffle(idx.begin(), idx.end()); 118 | return idx; 119 | } 120 | 121 | template std::vector choice(size_t n, T lower, T upper) { 122 | assert(n <= upper - lower + 1); 123 | std::set res; 124 | while (res.size() < n) res.insert(uniform(lower, upper)); 125 | return {res.begin(), res.end()}; 126 | } 127 | }; 128 | Random& global_gen() { 129 | static Random gen; 130 | return gen; 131 | } 132 | Random get_random_gen() { 133 | return Random(chrono::steady_clock::now().time_since_epoch().count()); 134 | } 135 | Random& global_runtime_gen() { 136 | static Random gen = get_random_gen(); 137 | return gen; 138 | } 139 | -------------------------------------------------------------------------------- /src/util/stack_extend.hpp: -------------------------------------------------------------------------------- 1 | // stack sizeを拡張する 64bit用 2 | int main() { 3 | static ll eord, enew; 4 | const int sz = 256*1024*1024; 5 | static unsigned char *p = (unsigned char*)malloc(sz); 6 | enew = ((ll)(p+sz-1) & ~0xff); 7 | __asm__ volatile("mov %%rsp, %0" : "=r"(eord)); 8 | __asm__ volatile("mov %0, %%rsp" : : "r"(enew)); 9 | main2(); 10 | __asm__ volatile("mov %0, %%rsp" : : "r"(eord)); 11 | return 0; 12 | } 13 | -------------------------------------------------------------------------------- /src/util/stopwatch.hpp: -------------------------------------------------------------------------------- 1 | struct StopWatch { 2 | bool f = false; 3 | clock_t st; 4 | void start() { 5 | f = true; 6 | st = clock(); 7 | } 8 | int msecs() { 9 | assert(f); 10 | return int(1LL * (clock()-st)*1000 / CLOCKS_PER_SEC); 11 | } 12 | }; 13 | -------------------------------------------------------------------------------- /test-oj/aplusb.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | using namespace std; 6 | 7 | void solve_aplusb() { 8 | int a, b; 9 | cin >> a >> b; 10 | cout << a + b << endl; 11 | } -------------------------------------------------------------------------------- /test-oj/bimaching.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/bipartitematching" 2 | 3 | #include "base.hpp" 4 | #include "util/fast_io.hpp" 5 | #include "graph/bimaching.hpp" 6 | 7 | int main() { 8 | Scanner sc(stdin); 9 | Printer pr(stdout); 10 | int l, r, m; 11 | sc.read(l, r, m); 12 | V> edges(m); 13 | for (int i = 0; i < m; i++) { 14 | sc.read(edges[i].first, edges[i].second); 15 | } 16 | BipartiteMaching bm(l, r, edges); 17 | V> ans; 18 | for (int i = 0; i < l; i++) { 19 | if (bm.lmt[i] != -1) { 20 | ans.push_back({i, bm.lmt[i]}); 21 | } 22 | } 23 | pr.writeln(ans.size()); 24 | for (auto p : ans) { 25 | pr.writeln(p.first, p.second); 26 | } 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /test-oj/comb.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/aplusb" 2 | 3 | #include "base.hpp" 4 | #include "math/modint.hpp" 5 | #include "math/dynamicmodint.hpp" 6 | #include "math/comb.hpp" 7 | 8 | #include "aplusb.hpp" 9 | 10 | using Mint = ModInt; 11 | using DMint = DynamicModInt; 12 | int main() { 13 | { 14 | Comb c(100); 15 | assert(c.fact[33] * c.ifact[33] == Mint(1)); 16 | assert(c.fact[100] * c.ifact[100] == Mint(1)); 17 | } 18 | { 19 | DMint::set_mod(103); 20 | Comb c(100); 21 | assert(c.fact[33] * c.ifact[33] == DMint(1)); 22 | assert(c.fact[100] * c.ifact[100] == DMint(1)); 23 | } 24 | 25 | solve_aplusb(); 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /test-oj/dbg.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/aplusb" 2 | 3 | #define LOCAL 4 | #include "aplusb.hpp" 5 | #include "base.hpp" 6 | 7 | int main() { 8 | pair a = {1, 2}; 9 | dbg(a); 10 | V b = {1, 2, 3}; 11 | dbg(b); 12 | V> c = {{1, 2}, {3, 4}}; 13 | dbg(c); 14 | pair, V> d = {{1, 2}, {3, 4, 5}}; 15 | dbg(d); 16 | 17 | array e = {1, 2, 3}; 18 | dbg(e); 19 | array, 2> f = {{{1, 2, 3}, {4, 5}}}; 20 | dbg(f); 21 | 22 | set g = {1, 2, 3, 4}; 23 | dbg(g); 24 | 25 | map h; h[1] = 2; h[3] = 4; 26 | dbg(h); 27 | 28 | solve_aplusb(); 29 | 30 | __int128_t x = 1234; 31 | dbg(x); 32 | __uint128_t y = 5678; 33 | dbg(y); 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /test-oj/doublingsa.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/suffixarray" 2 | 3 | #include "base.hpp" 4 | #include "util/fast_io.hpp" 5 | #include "string/suffixarray.hpp" 6 | 7 | int main() { 8 | Scanner sc(stdin); 9 | Printer pr(stdout); 10 | string s; 11 | sc.read(s); 12 | auto sa = doublingSA(s); 13 | pr.writeln(V{sa.begin() + 1, sa.end()}); 14 | } 15 | -------------------------------------------------------------------------------- /test-oj/fenwick_2d_rectangle_sum.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/rectangle_sum" 2 | 3 | #include "base.hpp" 4 | #include "util/fast_io.hpp" 5 | #include "datastructure/fenwick2d.hpp" 6 | 7 | int main() { 8 | Scanner sc(stdin); 9 | Printer pr(stdout); 10 | int n, q; 11 | sc.read(n, q); 12 | using P = pair; 13 | V

ps(n); 14 | V w(n); 15 | for (int i = 0; i < n; i++) { 16 | sc.read(ps[i].first, ps[i].second, w[i]); 17 | } 18 | auto f2d = Fenwick2D(ps); 19 | for (int i = 0; i < n; i++) { 20 | f2d.add(ps[i], w[i]); 21 | } 22 | for (int i = 0; i < q; i++) { 23 | int l, d, r, u; 24 | sc.read(l, d, r, u); 25 | pr.writeln(f2d.sum({l, d}, {r, u})); 26 | } 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /test-oj/hashmap.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/associative_array" 2 | 3 | #include "base.hpp" 4 | #include "util/fast_io.hpp" 5 | #include "datastructure/hashmap.hpp" 6 | 7 | int main() { 8 | Scanner sc(stdin); 9 | Printer pr(stdout); 10 | 11 | int q; 12 | sc.read(q); 13 | HashMap mp; 14 | 15 | for (int ph = 0; ph < q; ph++) { 16 | int ty; 17 | sc.read(ty); 18 | if (ty == 0) { 19 | ll k, v; 20 | sc.read(k, v); 21 | mp.set(k, v); 22 | } else { 23 | ll k; 24 | sc.read(k); 25 | pr.writeln(mp.get(k)); 26 | } 27 | } 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /test-oj/hashmap_remove.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/associative_array" 2 | 3 | #include "base.hpp" 4 | #include "util/fast_io.hpp" 5 | #include "datastructure/hashmap.hpp" 6 | 7 | int main() { 8 | Scanner sc(stdin); 9 | Printer pr(stdout); 10 | 11 | int q; 12 | sc.read(q); 13 | HashMap mp; 14 | 15 | for (int ph = 0; ph < q; ph++) { 16 | int ty; 17 | sc.read(ty); 18 | if (ty == 0) { 19 | ll k, v; 20 | sc.read(k, v); 21 | if (v == 0) mp.remove(k); 22 | else mp.set(k, v); 23 | } else { 24 | ll k; 25 | sc.read(k); 26 | pr.writeln(mp.get(k)); 27 | } 28 | } 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /test-oj/hashset.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/aplusb" 2 | 3 | #include "base.hpp" 4 | #include "aplusb.hpp" 5 | #include "datastructure/hashset.hpp" 6 | 7 | int main() { 8 | HashSet st; 9 | 10 | for (int i = 0; i < 100; i++) { 11 | st.insert(i); 12 | assert(int(st.size()) == i + 1); 13 | } 14 | auto actual = st.to_vec(); 15 | sort(actual.begin(), actual.end()); 16 | V expect(100); 17 | iota(expect.begin(), expect.end(), 0); 18 | assert(expect == actual); 19 | solve_aplusb(); 20 | return 0; 21 | } 22 | -------------------------------------------------------------------------------- /test-oj/hashset_hashmap.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/associative_array" 2 | 3 | #include "base.hpp" 4 | #include "util/fast_io.hpp" 5 | #include "datastructure/hashset.hpp" 6 | #include "datastructure/hashmap.hpp" 7 | 8 | int main() { 9 | Scanner sc(stdin); 10 | Printer pr(stdout); 11 | 12 | int q; 13 | sc.read(q); 14 | HashSet st; 15 | HashMap mp; 16 | 17 | for (int ph = 0; ph < q; ph++) { 18 | int ty; 19 | sc.read(ty); 20 | if (ty == 0) { 21 | ll k, v; 22 | sc.read(k, v); 23 | if (v == 0) { 24 | st.erase(k); 25 | mp.remove(k); 26 | } else { 27 | st.insert(k); 28 | mp.set(k, v); 29 | } 30 | } else { 31 | ll k; 32 | sc.read(k); 33 | ll u = mp.get(k); 34 | assert(st.count(k) == (u != 0)); 35 | pr.writeln(u); 36 | } 37 | } 38 | return 0; 39 | } 40 | -------------------------------------------------------------------------------- /test-oj/hl_lca.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/lca" 2 | 3 | #include "base.hpp" 4 | #include "util/fast_io.hpp" 5 | #include "tree/hl.hpp" 6 | 7 | int main() { 8 | Scanner sc(stdin); 9 | Printer pr(stdout); 10 | int n, q; 11 | sc.read(n, q); 12 | struct E { int to; }; 13 | VV g(n); 14 | for (int i = 1; i < n; i++) { 15 | int p; 16 | sc.read(p); 17 | g[p].push_back({i}); 18 | g[i].push_back({p}); 19 | } 20 | auto hl = get_hl(g, 0); 21 | for (int i = 0; i < q; i++) { 22 | int u, v; 23 | sc.read(u, v); 24 | auto lca_id = hl.lca(u, v); 25 | pr.writeln(lca_id); 26 | } 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /test-oj/hl_vertex_add_path_sum.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/vertex_add_path_sum" 2 | 3 | #include "base.hpp" 4 | #include "datastructure/segtree.hpp" 5 | #include "tree/hl.hpp" 6 | #include "util/fast_io.hpp" 7 | 8 | int main() { 9 | Scanner sc(stdin); 10 | Printer pr(stdout); 11 | int n, q; 12 | sc.read(n, q); 13 | V a(n); 14 | for (int i = 0; i < n; i++) { 15 | sc.read(a[i]); 16 | } 17 | struct E { 18 | int to; 19 | }; 20 | VV g(n); 21 | for (int i = 0; i < n - 1; i++) { 22 | int u, v; 23 | sc.read(u, v); 24 | g[u].push_back({v}); 25 | g[v].push_back({u}); 26 | } 27 | auto hl = get_hl(g, 0); 28 | auto seg = 29 | get_simple_seg(V(n, 0), 0LL, [&](ll x, ll y) { return x + y; }); 30 | for (int i = 0; i < n; i++) { 31 | seg.set(hl.ord(i).i, a[i]); 32 | } 33 | for (int i = 0; i < q; i++) { 34 | int t; 35 | sc.read(t); 36 | if (t == 0) { 37 | int p; 38 | ll x; 39 | sc.read(p, x); 40 | seg.set(hl.ord(p).i, seg.single(hl.ord(p).i) + x); 41 | } else { 42 | int u, v; 43 | sc.read(u, v); 44 | int l = hl.lca(u, v); 45 | ll sm = seg.single(hl.ord(l).i); 46 | hl.get_path(l, u, [&](HL::I x, HL::I y) { sm += seg.sum(x.i, y.i + 1); }); 47 | hl.get_path(l, v, [&](HL::I x, HL::I y) { sm += seg.sum(x.i, y.i + 1); }); 48 | pr.writeln(sm); 49 | } 50 | } 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /test-oj/hl_vertex_add_subtree_sum.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/vertex_add_subtree_sum" 2 | 3 | #include "base.hpp" 4 | #include "datastructure/segtree.hpp" 5 | #include "tree/hl.hpp" 6 | #include "util/fast_io.hpp" 7 | 8 | int main() { 9 | Scanner sc(stdin); 10 | Printer pr(stdout); 11 | int n, q; 12 | sc.read(n, q); 13 | V a(n); 14 | for (int i = 0; i < n; i++) { 15 | sc.read(a[i]); 16 | } 17 | struct E { 18 | int to; 19 | }; 20 | VV g(n); 21 | for (int i = 1; i < n; i++) { 22 | int p; 23 | sc.read(p); 24 | g[i].push_back({p}); 25 | g[p].push_back({i}); 26 | } 27 | auto hl = get_hl(g, 0); 28 | auto seg = 29 | get_simple_seg(V(n, 0), 0LL, [&](ll x, ll y) { return x + y; }); 30 | for (int i = 0; i < n; i++) { 31 | seg.set(hl.ord(i).i, a[i]); 32 | } 33 | for (int i = 0; i < q; i++) { 34 | int t; 35 | sc.read(t); 36 | if (t == 0) { 37 | int p; 38 | ll x; 39 | sc.read(p, x); 40 | seg.set(hl.ord(p).i, seg.single(hl.ord(p).i) + x); 41 | } else { 42 | int u; 43 | sc.read(u); 44 | ll sm = seg.sum(hl.ord(u).i, hl.subtree_out(u).i); 45 | pr.writeln(sm); 46 | } 47 | } 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /test-oj/inv_of_formal_power_series.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/inv_of_formal_power_series" 2 | 3 | #include "base.hpp" 4 | #include "util/fast_io.hpp" 5 | #include "math/modint.hpp" 6 | #include "util/random.hpp" 7 | #include "math/nft.hpp" 8 | #include "math/poly.hpp" 9 | 10 | using Mint = ModInt<998244353>; 11 | template <> const Mint Mint::G = Mint(3); 12 | 13 | int main() { 14 | Scanner sc(stdin); 15 | Printer pr(stdout); 16 | 17 | int n; 18 | sc.read(n); 19 | V _a(n); 20 | for (int i = 0; i < n; i++) { 21 | int x; 22 | sc.read(x); 23 | _a[i] = Mint(x); 24 | } 25 | Poly a = _a; 26 | auto b = a.inv(n); 27 | 28 | for (int i = 0; i < n; i++) { 29 | pr.write(b.freq(i).v); 30 | pr.write(' '); 31 | } 32 | pr.writeln(); 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /test-oj/lctree_lca.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/lca" 2 | 3 | #include "base.hpp" 4 | #include "util/fast_io.hpp" 5 | #include "datastructure/linkcuttree.hpp" 6 | 7 | struct Node { 8 | using D = bool; 9 | static D e_d() { return false; } 10 | static D op_dd(const D&, const D&) { return false; } 11 | static D rev(const D&) { return false; } 12 | }; 13 | 14 | int main() { 15 | Scanner sc(stdin); 16 | Printer pr(stdout); 17 | int n, q; 18 | sc.read(n, q); 19 | V> lct(n); 20 | for (int i = 1; i < n; i++) { 21 | int p; 22 | sc.read(p); 23 | lct[i].link(&(lct[p])); 24 | } 25 | for (int i = 0; i < q; i++) { 26 | int u, v; 27 | sc.read(u, v); 28 | auto lca_id = int(lct[u].lca(&(lct[v])) - &(lct[0])); 29 | pr.writeln(lca_id); 30 | } 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /test-oj/lctree_vertex_add_path_sum.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/vertex_add_path_sum" 2 | 3 | #include "base.hpp" 4 | #include "util/fast_io.hpp" 5 | #include "datastructure/linkcuttree.hpp" 6 | 7 | struct Node { 8 | using D = ll; 9 | static D e_d() { 10 | return 0; 11 | } 12 | static D op_dd(const D& l, const D& r) { 13 | return l + r; 14 | } 15 | static D rev(const D& x) { 16 | return x; 17 | } 18 | }; 19 | 20 | int main() { 21 | Scanner sc(stdin); 22 | Printer pr(stdout); 23 | int n, q; 24 | sc.read(n, q); 25 | V> lct(n); 26 | for (int i = 0; i < n; i++) { 27 | ll a; 28 | sc.read(a); 29 | lct[i].init_node(a); 30 | } 31 | for (int i = 0; i < n - 1; i++) { 32 | int u, v; 33 | sc.read(u, v); 34 | lct[u].link(&(lct[v])); 35 | } 36 | for (int i = 0; i < q; i++) { 37 | int t; 38 | sc.read(t); 39 | if (t == 0) { 40 | int p; ll x; 41 | sc.read(p, x); 42 | lct[p].expose(); 43 | lct[p].single_add(x); 44 | } else { 45 | int u, v; 46 | sc.read(u, v); 47 | lct[u].evert(); 48 | lct[v].expose(); 49 | pr.writeln(lct[v].sm); 50 | } 51 | } 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /test-oj/max_clique.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/maximum_independent_set" 2 | 3 | #include "base.hpp" 4 | #include "util/fast_io.hpp" 5 | #include "graph/maxclique.hpp" 6 | 7 | int main() { 8 | Scanner sc(stdin); 9 | Printer pr(stdout); 10 | 11 | int n, m; 12 | sc.read(n, m); 13 | VV graph(n, V(n, 1)); 14 | for (int i = 0; i < n; i++) { 15 | graph[i][i] = 0; 16 | } 17 | for (int i = 0; i < m; i++) { 18 | int a, b; 19 | sc.read(a, b); 20 | graph[a][b] = graph[b][a] = 0; 21 | } 22 | 23 | struct E { 24 | int to; 25 | }; 26 | VV g(n); 27 | for (int i = 0; i < n; i++) { 28 | for (int j = 0; j < n; j++) { 29 | if (graph[i][j]) g[i].push_back({j}); 30 | } 31 | } 32 | 33 | auto answer = MaxClique<40, E>(g).clique; 34 | 35 | int x = int(answer.size()); 36 | pr.writeln(x); 37 | for (int i = 0; i < x; i++) { 38 | pr.write(answer[i]); 39 | if (i != x - 1) pr.write(" "); 40 | } 41 | pr.writeln(); 42 | } 43 | -------------------------------------------------------------------------------- /test-oj/modint.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/aplusb" 2 | 3 | #include "aplusb.hpp" 4 | 5 | #include "base.hpp" 6 | #include "math/dynamicmodint.hpp" 7 | 8 | using DMint = DynamicModInt; 9 | 10 | int main() { 11 | DMint::set_mod(103); 12 | for (int i = 1; i < 103; i++) { 13 | ll a = DMint(i).inv().val(); 14 | assert(1 <= a && a < 103); 15 | assert((a * i) % 103 == 1); 16 | } 17 | solve_aplusb(); 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /test-oj/modint61.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/aplusb" 2 | 3 | #include "aplusb.hpp" 4 | 5 | #include "base.hpp" 6 | #include "math/modint61.hpp" 7 | #include "util/random.hpp" 8 | 9 | using Mint = ModInt61; 10 | 11 | int main() { 12 | Random gen = Random(); 13 | for (int ph = 0; ph < 100; ph++) { 14 | ull a = gen.uniform(0ULL, Mint::get_mod() - 1); 15 | ull b = gen.uniform(0ULL, Mint::get_mod() - 1); 16 | ull expect = (__uint128_t(a) + b) % Mint::get_mod(); 17 | ull actual = (Mint(a) + Mint(b)).v; 18 | assert(expect == actual); 19 | } 20 | for (int ph = 0; ph < 100; ph++) { 21 | ull a = gen.uniform(0ULL, Mint::get_mod() - 1); 22 | ull b = gen.uniform(0ULL, Mint::get_mod() - 1); 23 | ull expect = (__uint128_t(a) - b + Mint::get_mod()) % Mint::get_mod(); 24 | ull actual = (Mint(a) - Mint(b)).v; 25 | assert(expect == actual); 26 | } 27 | for (int ph = 0; ph < 100; ph++) { 28 | ull a = gen.uniform(0ULL, Mint::get_mod() - 1); 29 | ull b = gen.uniform(0ULL, Mint::get_mod() - 1); 30 | ull expect = __uint128_t(a) * b % Mint::get_mod(); 31 | ull actual = (Mint(a) * Mint(b)).v; 32 | assert(expect == actual); 33 | } 34 | for (int ph = 0; ph < 100; ph++) { 35 | Mint a = Mint(gen.uniform(0ULL, Mint::get_mod() - 1)); 36 | Mint ia = a.inv(); 37 | assert((a * ia).v == 1); 38 | } 39 | solve_aplusb(); 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /test-oj/nft_convolution.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/convolution_mod" 2 | 3 | #include "base.hpp" 4 | #include "util/fast_io.hpp" 5 | #include "bitop.hpp" 6 | #include "math/modint.hpp" 7 | #include "math/nft.hpp" 8 | 9 | using Mint = ModInt<998244353>; 10 | template <> const Mint Mint::G = Mint(3); 11 | 12 | int main() { 13 | Scanner sc(stdin); 14 | Printer pr(stdout); 15 | 16 | int n, m; 17 | sc.read(n, m); 18 | 19 | V a(n); 20 | for (int i = 0; i < n; i++) { 21 | sc.read(a[i].v); 22 | } 23 | V b(m); 24 | for (int i = 0; i < m; i++) { 25 | sc.read(b[i].v); 26 | } 27 | auto c = multiply(a, b); 28 | for (auto x : c) { 29 | pr.write(x.v); 30 | pr.write(' '); 31 | } 32 | pr.writeln(); 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /test-oj/nimber.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/nim_product_64" 2 | 3 | #include "base.hpp" 4 | #include "util/fast_io.hpp" 5 | #include "math/nimber.hpp" 6 | 7 | int main() { 8 | Scanner sc(stdin); 9 | Printer pr(stdout); 10 | int t; 11 | sc.read(t); 12 | for (int i = 0; i < t; i++) { 13 | ull a, b; 14 | sc.read(a, b); 15 | pr.writeln((Nimber64(a) * Nimber64(b)).v); 16 | } 17 | return 0; 18 | } 19 | -------------------------------------------------------------------------------- /test-oj/number_of_substrings.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/number_of_substrings" 2 | 3 | #include "base.hpp" 4 | #include "util/fast_io.hpp" 5 | #include "string/suffixarray.hpp" 6 | 7 | int main() { 8 | Scanner sc(stdin); 9 | Printer pr(stdout); 10 | string s; 11 | sc.read(s); 12 | auto sai = SA(s, sa_is(s)); 13 | int n = int(s.size()); 14 | ll ans = 0; 15 | for (int i = 0; i < n; i++) { 16 | ans += max(0, (n - sai.sa[i + 1]) - sai.lcp[i]); 17 | } 18 | pr.writeln(ans); 19 | } 20 | -------------------------------------------------------------------------------- /test-oj/online-zalgo.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/zalgorithm" 2 | 3 | #include "base.hpp" 4 | #include "util/fast_io.hpp" 5 | #include "string/onlinez.hpp" 6 | 7 | int main() { 8 | Scanner sc(stdin); 9 | Printer pr(stdout); 10 | string s; 11 | sc.read(s); 12 | int n = int(s.size()); 13 | s += "$"; 14 | 15 | V z(n, -1); 16 | z[0] = n; 17 | OnlineZ oz; 18 | for (int i = 0; i <= n; i++) { 19 | auto v = oz.inc(s[i]); 20 | for (int x: v) { 21 | z[x] = i - x; 22 | } 23 | } 24 | pr.writeln(z); 25 | } 26 | -------------------------------------------------------------------------------- /test-oj/printer.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/aplusb" 2 | 3 | #include "aplusb.hpp" 4 | #include "base.hpp" 5 | #include "util/fast_io.hpp" 6 | 7 | int main() { 8 | Printer pr(tmpfile()); 9 | pr.writeln("Hello"); 10 | pr.writeln(string("World")); 11 | 12 | solve_aplusb(); 13 | } 14 | -------------------------------------------------------------------------------- /test-oj/rollinghash_zalgo.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/zalgorithm" 2 | 3 | #include "base.hpp" 4 | #include "util/fast_io.hpp" 5 | #include "string/rollinghash.hpp" 6 | 7 | int main() { 8 | H::init(TEN(6)); 9 | Scanner sc(stdin); 10 | Printer pr(stdout); 11 | string s; 12 | sc.read(s); 13 | int n = int(s.size()); 14 | V hs = {H()}; 15 | for (char c: s) { 16 | H nh = hs.back() + H(c); 17 | hs.push_back(nh); 18 | } 19 | dbg(H::powB[3]); 20 | for (int i = 0; i < n; i++) { 21 | int lw = 0, up = n - i + 1; 22 | while (up - lw > 1) { 23 | int md = (lw + up) / 2; 24 | if (hs[md] == hs[i + md].strip_left(hs[i])) { 25 | lw = md; 26 | } else { 27 | up = md; 28 | } 29 | } 30 | pr.write(lw); 31 | pr.write(' '); 32 | } 33 | pr.writeln(); 34 | } 35 | -------------------------------------------------------------------------------- /test-oj/run.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/runenumerate" 2 | 3 | #include "base.hpp" 4 | #include "util/fast_io.hpp" 5 | #include "string/run.hpp" 6 | 7 | int main() { 8 | Scanner sc(stdin); 9 | Printer pr(stdout); 10 | string s; 11 | sc.read(s); 12 | RunExec runexec(s); 13 | int m = int(runexec.runs.size()); 14 | int n = 0; 15 | for (auto v : runexec.runs) n += int(v.size()); 16 | 17 | pr.writeln(n); 18 | for (int i = 0; i < m; i++) { 19 | auto v = runexec.runs[i]; 20 | sort(v.begin(), v.end()); 21 | for (auto p : v) { 22 | pr.writeln(i, p.first, p.second); 23 | } 24 | } 25 | auto runs = RunExec(s); 26 | } 27 | -------------------------------------------------------------------------------- /test-oj/sais.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/suffixarray" 2 | 3 | #include "base.hpp" 4 | #include "util/fast_io.hpp" 5 | #include "string/suffixarray.hpp" 6 | 7 | int main() { 8 | Scanner sc(stdin); 9 | Printer pr(stdout); 10 | string s; 11 | sc.read(s); 12 | auto sa = sa_is(s); 13 | pr.writeln(V{sa.begin() + 1, sa.end()}); 14 | } 15 | -------------------------------------------------------------------------------- /test-oj/scanner.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/aplusb" 2 | 3 | #include "base.hpp" 4 | #include "util/fast_io.hpp" 5 | 6 | #include "aplusb.hpp" 7 | #include "unistd.h" 8 | 9 | void check_separator() { 10 | auto tmpf = tmpfile(); 11 | fputs(string(1 << 15, 'a').c_str(), tmpf); 12 | fputs(" ", tmpf); 13 | fputs(string(1 << 15, 'b').c_str(), tmpf); 14 | rewind(tmpf); 15 | Scanner sc(tmpf); 16 | string s, t; 17 | sc.read(s, t); 18 | assert(s == string(1 << 15, 'a')); 19 | assert(t == string(1 << 15, 'b')); 20 | } 21 | 22 | void check_interactive() { 23 | int pipefd[2]; 24 | assert(pipe(pipefd) == 0); 25 | 26 | Scanner sc(fdopen(pipefd[0], "r")); 27 | FILE* fw = fdopen(pipefd[1], "w"); 28 | fprintf(fw, "1234\n"); 29 | fflush(fw); 30 | int x; 31 | sc.read(x); 32 | assert(x == 1234); 33 | } 34 | 35 | int main() { 36 | check_separator(); 37 | check_interactive(); 38 | solve_aplusb(); 39 | } 40 | -------------------------------------------------------------------------------- /test-oj/scanner_many_aplusb.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/many_aplusb" 2 | 3 | #include "base.hpp" 4 | #include "util/fast_io.hpp" 5 | 6 | int main() { 7 | Scanner sc(stdin); 8 | Printer pr(stdout); 9 | 10 | int q; 11 | sc.read(q); 12 | 13 | for (int i = 0; i < q; i++) { 14 | ll a, b; 15 | sc.read(a, b); 16 | pr.writeln(a + b); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /test-oj/staticrangesum_rectangle_sum.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/rectangle_sum" 2 | 3 | #include "base.hpp" 4 | #include "util/fast_io.hpp" 5 | #include "datastructure/staticrangesum.hpp" 6 | 7 | int main() { 8 | Scanner sc(stdin); 9 | Printer pr(stdout); 10 | int n, q; 11 | sc.read(n, q); 12 | V::P> ps(n); 13 | for (int i = 0; i < n; i++) { 14 | sc.read(ps[i].x, ps[i].y, ps[i].val); 15 | } 16 | auto srs = StaticRangeSum(ps); 17 | for (int i = 0; i < q; i++) { 18 | int l, d, r, u; 19 | sc.read(l, d, r, u); 20 | pr.writeln(srs.sum(l, d, r, u)); 21 | } 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /test-oj/treedecomp_width2.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/tree_decomposition_width_2" 2 | 3 | #include "base.hpp" 4 | #include "util/fast_io.hpp" 5 | #include "graph/treedecomp.hpp" 6 | 7 | int main() { 8 | Scanner sc(stdin); 9 | Printer pr(stdout); 10 | 11 | string s; 12 | sc.read(s, s); 13 | int n, m; 14 | sc.read(n, m); 15 | VV g(n); 16 | for (int i = 0; i < m; i++) { 17 | int a, b; 18 | sc.read(a, b); a--; b--; 19 | g[a].push_back({b}); 20 | g[b].push_back({a}); 21 | } 22 | 23 | auto td = decomp_width2(g); 24 | int K = int(td.bags.size()); 25 | if (K == 0) { 26 | pr.writeln(-1); 27 | return 0; 28 | } 29 | pr.writeln("s", "td", K, 2, n); 30 | 31 | for (int i = 0; i < K; i++) { 32 | pr.write("b", i + 1); 33 | for (int j: td.bags[i]) { 34 | pr.write(' '); 35 | pr.write(j + 1); 36 | } 37 | pr.writeln(); 38 | } 39 | for (int i = 0; i < K; i++) { 40 | for (auto e: td.tr[i]) { 41 | int j = e.to; 42 | if (i < j) { 43 | pr.writeln(i + 1, j + 1); 44 | } 45 | } 46 | } 47 | return 0; 48 | } 49 | -------------------------------------------------------------------------------- /test-oj/unionfind.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/unionfind" 2 | 3 | #include "base.hpp" 4 | #include "util/fast_io.hpp" 5 | #include "datastructure/unionfind.hpp" 6 | 7 | int main() { 8 | Scanner sc(stdin); 9 | Printer pr(stdout); 10 | int n, q; 11 | sc.read(n, q); 12 | auto uf = UnionFind(n); 13 | for (int i = 0; i < q; i++) { 14 | int t, u, v; 15 | sc.read(t, u, v); 16 | if (t == 0) { 17 | uf.merge(u, v); 18 | } else { 19 | pr.writeln(uf.same(u, v) ? 1 : 0); 20 | } 21 | } 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /test-oj/zalgo.test.cpp: -------------------------------------------------------------------------------- 1 | #define PROBLEM "https://judge.yosupo.jp/problem/zalgorithm" 2 | 3 | #include "base.hpp" 4 | #include "util/fast_io.hpp" 5 | #include "string/zalgo.hpp" 6 | 7 | int main() { 8 | Scanner sc(stdin); 9 | Printer pr(stdout); 10 | string s; 11 | sc.read(s); 12 | auto z = z_algo(s); z.pop_back(); 13 | pr.writeln(z); 14 | } 15 | --------------------------------------------------------------------------------