[
  {
    "path": "README.md",
    "content": "AtCoder解説放送ライブラリ集\r\n----\r\n## これは何？\r\n[解説放送](https://www.youtube.com/channel/UCtG3StnbhxHxXfE6Q4cPZwQ)で作ったライブラリを公開しています。\r\n\r\n## 目次\r\n\r\n### ユーティリティ\r\n|名前|コード|説明|\r\n|:--|:--|:--|\r\n|テンプレート|[template.cpp](template.cpp)||\r\n|ModInt|[mint.cpp](mint.cpp)|自動でmodを取ってくれる整数型|\r\n|座標圧縮|[cc.cpp](cc.cpp)|座標に昇順に番号を振る|\r\n|順列|[perm.cpp](perm.cpp)|置換の合成や逆元等|\r\n\r\n### データ構造\r\n|名前|コード|説明|\r\n|:--|:--|:--|\r\n|BIT|[bit.cpp](bit.cpp)|Binary Indexed Tree (Fenwick Tree)|\r\n|UnionFind|[uf.cpp](uf.cpp)|Union Find (DSU)|\r\n|CHT|[cht.cpp](cht.cpp)|Convex Hull Trick|\r\n|CartesianTree|[cart.cpp](cart.cpp)|Cartesian Tree|\r\n\r\n### 数学\r\n|名前|コード|説明|\r\n|:--|:--|:--|\r\n|GCD/LCM|[gcd.cpp](gcd.cpp)|最大公約数と最小公倍数|\r\n|extgcd|[extgcd.cpp](extgcd.cpp)|Ai+Bj=gcd(A,B)なるi,jを求める|\r\n|Combination|[comb.cpp](comb.cpp)|nCkをmod素数で求める|\r\n|Matrix|[mat.cpp](mat.cpp)|行列|\r\n|素数|[prime.cpp](prime.cpp)|素数列挙と素因数分解|\r\n|FPS|[fps.cpp](fps.cpp)|形式的べき級数|\r\n\r\n### グラフ\r\n|名前|コード|説明|\r\n|:--|:--|:--|\r\n|LCA|[lca.cpp](lca.cpp)|最小共通祖先|\r\n|全方位木DP|[rerooting.cpp](rerooting.cpp)|全方位木DP|\r\n\r\n### 文字列\r\n|名前|コード|説明|\r\n|:--|:--|:--|\r\n|KMP|[mp.cpp](mp.cpp)|文字列検索アルゴリズム（正確にはMP）|\r\n|Z|[z.cpp](z.cpp)|Z-algorithm|\r\n|Aho-Corasick|[aho.cpp](aho.cpp)|文字列集合へのマッチを検出する|\r\n\r\n### 幾何\r\n|名前|コード|説明|\r\n|:--|:--|:--|\r\n|基本|[geom.cpp](geom.cpp)|幾何のベース＋目次|\r\n|Vector|[geom/vector.cpp](geom/vector.cpp)|ベクトル（点を扱う際にも使う）|\r\n|Line|[geom/line.cpp](geom/line.cpp)|直線・線分|\r\n|Circle|[geom/circle.cpp](geom/circle.cpp)|円|"
  },
  {
    "path": "aho.cpp",
    "content": "// Aho-Corasick\r\n// https://youtu.be/BYoRvdgI5EU?t=9633\r\nstruct Aho {\r\n  using MP = unordered_map<char,int>;\r\n  vector<MP> to;\r\n  vector<int> cnt, fail;\r\n  Aho(): to(1), cnt(1) {}\r\n  int add(const string& s) {\r\n    int v = 0;\r\n    for (char c : s) {\r\n      if (!to[v].count(c)) {\r\n        to[v][c] = to.size();\r\n        to.push_back(MP());\r\n        cnt.push_back(0);\r\n      }\r\n      v = to[v][c];\r\n    }\r\n    cnt[v]++;\r\n    return v;\r\n  }\r\n  void init() {\r\n    fail = vector<int>(to.size(), -1);\r\n    queue<int> q;\r\n    q.push(0);\r\n    while (!q.empty()) {\r\n      int v = q.front(); q.pop();\r\n      for (auto [c,u] : to[v]) {\r\n        fail[u] = (*this)(fail[v],c);\r\n        cnt[u] += cnt[fail[u]];\r\n        q.push(u);\r\n      }\r\n    }\r\n  }\r\n  int operator()(int v, char c) const {\r\n    while (v != -1) {\r\n      auto it = to[v].find(c);\r\n      if (it != to[v].end()) return it->second;\r\n      v = fail[v];\r\n    }\r\n    return 0;\r\n  }\r\n  int operator[](int v) const { return cnt[v];}\r\n};"
  },
  {
    "path": "bit.cpp",
    "content": "// Binary Indexed Tree (Fenwick Tree)\r\n// https://youtu.be/lyHk98daDJo?t=7960\r\ntemplate<typename T>\r\nstruct BIT {\r\n  int n;\r\n  vector<T> d;\r\n  BIT(int n=0):n(n),d(n+1) {}\r\n  void add(int i, T x=1) {\r\n    for (i++; i <= n; i += i&-i) {\r\n      d[i] += x;\r\n    }\r\n  }\r\n  T sum(int i) {\r\n    T x = 0;\r\n    for (i++; i; i -= i&-i) {\r\n      x += d[i];\r\n    }\r\n    return x;\r\n  }\r\n  T sum(int l, int r) {\r\n    return sum(r-1) - sum(l-1);\r\n  }\r\n};"
  },
  {
    "path": "cart.cpp",
    "content": "// Cartesian Tree\n// https://youtu.be/XVu8-ZnuOiA?t=9291\ntemplate<class T=long long>\nstruct CartesianTree {\n  int n, root;\n  vector<int> l, r;\n  CartesianTree() {}\n  CartesianTree(const vector<T>& a, bool _max=true) {\n    n = a.size();\n    l = r = vector<int>(n,-1);\n    vector<int> st;\n    rep(i,n) {\n      int p = -1;\n      while (st.size() && !((a[st.back()] < a[i])^_max)) {\n        int j = st.back(); st.pop_back();\n        r[j] = p; p = j;\n      }\n      l[i] = p;\n      st.push_back(i);\n    }\n    rep(i,st.size()-1) r[st[i]] = st[i+1];\n    root = st[0];\n  }\n};"
  },
  {
    "path": "cc.cpp",
    "content": "// Coodinate Compression\r\n// https://youtu.be/fR3W5IcBGLQ?t=8550\r\ntemplate<typename T=int>\r\nstruct CC {\r\n  bool initialized;\r\n  vector<T> xs;\r\n  CC(): initialized(false) {}\r\n  void add(T x) { xs.push_back(x);}\r\n  void init() {\r\n    sort(xs.begin(), xs.end());\r\n    xs.erase(unique(xs.begin(),xs.end()),xs.end());\r\n    initialized = true;\r\n  }\r\n  int operator()(T x) {\r\n    if (!initialized) init();\r\n    return upper_bound(xs.begin(), xs.end(), x) - xs.begin() - 1;\r\n  }\r\n  T operator[](int i) {\r\n    if (!initialized) init();\r\n    return xs[i];\r\n  }\r\n  int size() {\r\n    if (!initialized) init();\r\n    return xs.size();\r\n  }\r\n};"
  },
  {
    "path": "cht.cpp",
    "content": "// Convex Hull Trick (max)\r\n// https://youtu.be/TSvXG35mmRE?t=7853\r\nstruct CHT {\r\n  struct Linear {\r\n    ll a, b;\r\n    Linear(ll a=0, ll b=0): a(a), b(b) {}\r\n    ll operator()(ll x) const { return a*x+b;}\r\n  };\r\n  deque<Linear> ls;\r\n  void add(ll a, ll b) {\r\n    Linear l(a,b);\r\n    assert(ls.size() == 0 || ls.back().a <= l.a);\r\n    while (ls.size() >= 2) {\r\n      const Linear& l1 = ls[ls.size()-2];\r\n      const Linear& l2 = ls.back();\r\n      if ((l.a-l2.a)*(l1.b-l2.b) < (l2.a-l1.a)*(l2.b-l.b)) break;\r\n      ls.pop_back();\r\n    }\r\n    ls.push_back(l);\r\n  }\r\n  ll operator()(ll x) { // x: asc\r\n    ll res = ls[0](x);\r\n    while (ls.size() >= 2) {\r\n      ll now = ls[1](x);\r\n      if (now < res) break;\r\n      res = now;\r\n      ls.pop_front();\r\n    }\r\n    return res;\r\n  }\r\n};"
  },
  {
    "path": "comb.cpp",
    "content": "// combination mod prime\r\n// https://youtu.be/8uowVvQ_-Mo?t=6002\r\n// https://youtu.be/Tgd_zLfRZOQ?t=9928\r\nstruct modinv {\r\n  int n; vector<mint> d;\r\n  modinv(): n(2), d({0,1}) {}\r\n  mint operator()(int i) {\r\n    while (n <= i) d.push_back(-d[mint::mod()%n]*(mint::mod()/n)), ++n;\r\n    return d[i];\r\n  }\r\n  mint operator[](int i) const { return d[i];}\r\n} invs;\r\nstruct modfact {\r\n  int n; vector<mint> d;\r\n  modfact(): n(2), d({1,1}) {}\r\n  mint operator()(int i) {\r\n    while (n <= i) d.push_back(d.back()*n), ++n;\r\n    return d[i];\r\n  }\r\n  mint operator[](int i) const { return d[i];}\r\n} facts;\r\nstruct modfactinv {\r\n  int n; vector<mint> d;\r\n  modfactinv(): n(2), d({1,1}) {}\r\n  mint operator()(int i) {\r\n    while (n <= i) d.push_back(d.back()*invs(n)), ++n;\r\n    return d[i];\r\n  }\r\n  mint operator[](int i) const { return d[i];}\r\n} ifacts;\r\nmint comb(int n, int k) {\r\n  if (n < k || k < 0) return 0;\r\n  return facts(n)*ifacts(k)*ifacts(n-k);\r\n}"
  },
  {
    "path": "extgcd.cpp",
    "content": "// ai+bj=g\r\n// https://youtu.be/fDJpXN2R75A?t=6895\r\nll extgcd(ll a, ll b, ll& i, ll& j) {\r\n  if (b == 0) { i = 1; j = 0; return a;}\r\n  ll p = a/b, g = extgcd(b,a-b*p,j,i);\r\n  j -= p*i;\r\n  return g;\r\n}"
  },
  {
    "path": "fps.cpp",
    "content": "// Formal Power Series\r\nusing vm = vector<mint>;\r\nstruct fps : vm {\r\n#define d (*this)\r\n#define s int(vm::size())\r\n  template<class...Args> fps(Args...args): vm(args...) {}\r\n  fps(initializer_list<mint> a): vm(a.begin(),a.end()) {}\r\n  void rsz(int n) { if (s < n) resize(n);}\r\n  fps& low_(int n) { resize(n); return d;}\r\n  fps low(int n) const { return fps(d).low_(n);}\r\n  mint& operator[](int i) { rsz(i+1); return vm::operator[](i);}\r\n  mint operator[](int i) const { return i<s ? vm::operator[](i) : 0;}\r\n  mint operator()(mint x) const {\r\n    mint r;\r\n    for (int i = s-1; i >= 0; --i) r = r*x+d[i];\r\n    return r;\r\n  }\r\n  fps operator-() const { fps r(d); rep(i,s) r[i] = -r[i]; return r;}\r\n  fps& operator+=(const fps& a) { rsz(a.size()); rep(i,a.size()) d[i] += a[i]; return d;}\r\n  fps& operator-=(const fps& a) { rsz(a.size()); rep(i,a.size()) d[i] -= a[i]; return d;}\r\n  fps& operator*=(const fps& a) { return d = convolution(d, a);}\r\n  fps& operator*=(mint a) { rep(i,s) d[i] *= a; return d;}\r\n  fps& operator/=(mint a) { rep(i,s) d[i] /= a; return d;}\r\n  fps operator+(const fps& a) const { return fps(d) += a;}\r\n  fps operator-(const fps& a) const { return fps(d) -= a;}\r\n  fps operator*(const fps& a) const { return fps(d) *= a;}\r\n  fps operator*(mint a) const { return fps(d) *= a;}\r\n  fps operator/(mint a) const { return fps(d) /= a;}\r\n  fps operator~() const {\r\n    fps r({d[0].inv()});\r\n    for (int i = 1; i < s; i <<= 1) r = r*mint(2) - (r*r*low(i<<1)).low(i<<1);\r\n    return r.low_(s);\r\n  }\r\n  fps& operator/=(const fps& a) { int w = s; d *= ~a; return d.low_(w);}\r\n  fps operator/(const fps& a) const { return fps(d) /= a;}\r\n  fps integ() const {\r\n    fps r;\r\n    rep(i,s) r[i+1] = d[i]/(i+1);\r\n    return r;\r\n  }\r\n#undef s\r\n#undef d\r\n};\r\nostream& operator<<(ostream&o,const fps&a) {\r\n  rep(i,a.size()) o<<(i?\" \":\"\")<<a[i].val();\r\n  return o;\r\n}"
  },
  {
    "path": "gcd.cpp",
    "content": "// GCD, LCM\r\n// https://youtu.be/8lm8o8L9Bmw?t=2285\r\n// https://youtu.be/XI8exXVxZ-Q?t=3595\r\n// https://youtu.be/F2p_e6iKxnk?t=843\r\nll gcd(ll a, ll b) { return b?gcd(b,a%b):a;}\r\nll lcm(ll a, ll b) { return a/gcd(a,b)*b;}"
  },
  {
    "path": "geom/circle.cpp",
    "content": "// Circle\r\n// coding: https://youtu.be/TdR816rqc3s?t=1750\r\n// comment: https://youtu.be/TdR816rqc3s?t=11609\r\nstruct Circle {\r\n  V o; double r;\r\n  Circle(V o=V(), double r=0) : o(o), r(r) {}\r\n  vector<V> crossPoint(const Circle& c) {\r\n    V v = c.o-o;\r\n    double l = v.norm();\r\n    if (equal(l, 0)) return {};\r\n    if (equal(l+r+c.r, max({l,r,c.r})*2)) {\r\n      if (equal(l+r,c.r)) return {o - v*(r/l)};\r\n      return {o + v*(r/l)};\r\n    }\r\n    if (l+r+c.r < max({l,r,c.r})*2) return {};\r\n    double x = (l*l + r*r - c.r*c.r) / (2*l);\r\n    double y = sqrt(r*r - x*x);\r\n    V mid = o + v*(x/l);\r\n    v = v.rotate90();\r\n    return {mid + v*(y/l), mid - v*(y/l)};\r\n  }\r\n  bool isInside(const V& p) const {\r\n    return (p-o).norm() < r+eps;\r\n  }\r\n};"
  },
  {
    "path": "geom/line.cpp",
    "content": "struct Line {\r\n  V s, t;\r\n  Line(V s=V(0,0), V t=V(0,0)):s(s),t(t){}\r\n  V dir() const { return t-s;}\r\n  V normalize() const { return dir().normalize();}\r\n  double norm() const { return dir().norm();}\r\n  /* +1: s-t,s-p : ccw\r\n   * -1: s-t,s-p : cw\r\n   * +2: t-s-p\r\n   * -2: s-t-p\r\n   *  0: s-p-t */\r\n  int ccw(const V& p) const {\r\n    if (dir().cross(p-s) > eps) return +1;\r\n    if (dir().cross(p-s) < -eps) return -1;\r\n    if (dir().dot(p-s) < -eps) return +2;\r\n    if (dir().dot(t-p) < -eps) return -2;\r\n    return 0;\r\n  }\r\n  bool touch(const Line& l) const {\r\n    int a = ccw(l.s)*ccw(l.t), b = l.ccw(s)*l.ccw(t);\r\n    return !a || !b || (a == -1 && b == -1);\r\n  }\r\n};"
  },
  {
    "path": "geom/vector.cpp",
    "content": "// Vector\r\n// https://youtu.be/UWbGRhF3Ozw?t=9564\r\nstruct V {\r\n  double x, y;\r\n  V(double x=0, double y=0): x(x), y(y) {}\r\n  V& operator+=(const V& v) { x += v.x; y += v.y; return *this;}\r\n  V operator+(const V& v) const { return V(*this) += v;}\r\n  V& operator-=(const V& v) { x -= v.x; y -= v.y; return *this;}\r\n  V operator-(const V& v) const { return V(*this) -= v;}\r\n  V& operator*=(double s) { x *= s; y *= s; return *this;}\r\n  V operator*(double s) const { return V(*this) *= s;}\r\n  V& operator/=(double s) { x /= s; y /= s; return *this;}\r\n  V operator/(double s) const { return V(*this) /= s;}\r\n  double dot(const V& v) const { return x*v.x + y*v.y;}\r\n  double cross(const V& v) const { return x*v.y - v.x*y;}\r\n  double norm2() const { return x*x + y*y;}\r\n  double norm() const { return sqrt(norm2());}\r\n  V normalize() const { return *this/norm();}\r\n  V rotate90() const { return V(y, -x);}\r\n  int ort() const { // orthant\r\n    if (abs(x) < eps && abs(y) < eps) return 0;\r\n    if (y > 0) return x>0 ? 1 : 2;\r\n    else return x>0 ? 4 : 3;\r\n  }\r\n  bool operator<(const V& v) const {\r\n    int o = ort(), vo = v.ort();\r\n    if (o != vo) return o < vo;\r\n    return cross(v) > 0;\r\n  }\r\n};\r\nistream& operator>>(istream& is, V& v) {\r\n  is >> v.x >> v.y; return is;\r\n}\r\nostream& operator<<(ostream& os, const V& v) {\r\n  os<<\"(\"<<v.x<<\",\"<<v.y<<\")\"; return os;\r\n}"
  },
  {
    "path": "geom.cpp",
    "content": "// Geometry\r\nconst double eps = 1e-9;\r\nbool equal(double a, double b) { return abs(a-b) < eps;}\r\n\r\n[geom/vector]\r\n[geom/line]\r\n[geom/circle]"
  },
  {
    "path": "lca.cpp",
    "content": "// Lowest Common Ancestor by binary lifting\r\n// https://youtu.be/8uowVvQ_-Mo?t=4306\r\ntemplate<typename T=int> // T: type of cost\r\nstruct lca {\r\n  int n, root, l;\r\n  vector<vector<int>> to;\r\n  vector<vector<T>> co;\r\n  vector<int> dep;\r\n  vector<T> costs;\r\n  vector<vector<int>> par;\r\n  lca(int n):n(n),to(n),co(n),dep(n),costs(n) {\r\n    l = 0;\r\n    while ((1<<l) < n) ++l;\r\n    par = vector<vector<int>>(n+1,vector<int>(l,n));\r\n  }\r\n  void addEdge(int a, int b, T c=0) {\r\n    to[a].push_back(b); co[a].push_back(c);\r\n    to[b].push_back(a); co[b].push_back(c);\r\n  }\r\n  void dfs(int v, int d=0, T c=0, int p=-1) {\r\n    if (p != -1) par[v][0] = p;\r\n    dep[v] = d;\r\n    costs[v] = c;\r\n    for (int i = 0; i < to[v].size(); ++i) {\r\n      int u = to[v][i];\r\n      if (u == p) continue;\r\n      dfs(u, d+1, c+co[v][i], v);\r\n    }\r\n  }\r\n\r\n  void init(int _root=0) {\r\n    root = _root;\r\n    dfs(root);\r\n    for (int i = 0; i < l-1; ++i) {\r\n      for (int v = 0; v < n; ++v) {\r\n        par[v][i+1] = par[par[v][i]][i];\r\n      }\r\n    }\r\n  }\r\n  // LCA\r\n  int up(int v, int k) {\r\n    for (int i = l-1; i >= 0; --i) {\r\n      int len = 1<<i;\r\n      if (k >= len) k -= len, v = par[v][i];\r\n    }\r\n    return v;\r\n  }\r\n  int operator()(int a, int b) {\r\n    if (dep[a] > dep[b]) swap(a,b);\r\n    b = up(b, dep[b]-dep[a]);\r\n    if (a == b) return a;\r\n    for (int i = l-1; i >= 0; --i) {\r\n      int na = par[a][i], nb = par[b][i];\r\n      if (na != nb) a = na, b = nb;\r\n    }\r\n    return par[a][0];\r\n  }\r\n  int length(int a, int b) {\r\n    int c = (*this)(a,b);\r\n    return dep[a]+dep[b]-dep[c]*2;\r\n  }\r\n  T dist(int a, int b) {\r\n    int c = (*this)(a,b);\r\n    return costs[a]+costs[b]-costs[c]*2;\r\n  }\r\n};"
  },
  {
    "path": "mat.cpp",
    "content": "// https://youtu.be/ylWYSurx10A?t=2352\r\ntemplate<typename T>\r\nstruct Matrix {\r\n  int h, w;\r\n  vector<vector<T>> d;\r\n  Matrix() {}\r\n  Matrix(int h, int w, T val=0): h(h), w(w), d(h, vector<T>(w,val)) {}\r\n  Matrix& unit() {\r\n    assert(h == w);\r\n    rep(i,h) d[i][i] = 1;\r\n    return *this;\r\n  }\r\n  const vector<T>& operator[](int i) const { return d[i];}\r\n  vector<T>& operator[](int i) { return d[i];}\r\n  Matrix operator*(const Matrix& a) const {\r\n    assert(w == a.h);\r\n    Matrix r(h, a.w);\r\n    rep(i,h)rep(k,w)rep(j,a.w) {\r\n      r[i][j] += d[i][k]*a[k][j];\r\n    }\r\n    return r;\r\n  }\r\n  Matrix pow(long long t) const {\r\n    assert(h == w);\r\n    if (!t) return Matrix(h,h).unit();\r\n    if (t == 1) return *this;\r\n    Matrix r = pow(t>>1);\r\n    r = r*r;\r\n    if (t&1) r = r*(*this);\r\n    return r;\r\n  }\r\n  // https://youtu.be/-j02o6__jgs?t=11273\r\n  /* mint only\r\n  mint det() {\r\n    assert(h == w);\r\n    mint res = 1;\r\n    rep(k,h) {\r\n      for (int i = k; i < h; ++i) {\r\n        if (d[i][k] == 0) continue;\r\n        if (i != k) {\r\n          swap(d[i],d[k]);\r\n          res = -res;\r\n        }\r\n      }\r\n      if (d[k][k] == 0) return 0;\r\n      res *= d[k][k];\r\n      mint inv = mint(1)/d[k][k];\r\n      rep(j,h) d[k][j] *= inv;\r\n      for (int i = k+1; i < h; ++i) {\r\n        mint c = d[i][k];\r\n        for (int j = k; j < h; ++j) d[i][j] -= d[k][j]*c;\r\n      }\r\n    }\r\n    return res;\r\n  }\r\n  //*/\r\n};"
  },
  {
    "path": "mint.cpp",
    "content": "// auto mod int\r\n// https://youtu.be/L8grWxBlIZ4?t=9858\r\n// https://youtu.be/ERZuLAxZffQ?t=4807 : optimize\r\n// https://youtu.be/8uowVvQ_-Mo?t=1329 : division\r\nconst int mod = 1000000007;\r\nconst int mod = 998244353;\r\nstruct mint {\r\n  ll x; // typedef long long ll;\r\n  mint(ll x=0):x((x%mod+mod)%mod){}\r\n  mint operator-() const { return mint(-x);}\r\n  mint& operator+=(const mint a) {\r\n    if ((x += a.x) >= mod) x -= mod;\r\n    return *this;\r\n  }\r\n  mint& operator-=(const mint a) {\r\n    if ((x += mod-a.x) >= mod) x -= mod;\r\n    return *this;\r\n  }\r\n  mint& operator*=(const mint a) { (x *= a.x) %= mod; return *this;}\r\n  mint operator+(const mint a) const { return mint(*this) += a;}\r\n  mint operator-(const mint a) const { return mint(*this) -= a;}\r\n  mint operator*(const mint a) const { return mint(*this) *= a;}\r\n  mint pow(ll t) const {\r\n    if (!t) return 1;\r\n    mint a = pow(t>>1);\r\n    a *= a;\r\n    if (t&1) a *= *this;\r\n    return a;\r\n  }\r\n\r\n  // for prime mod\r\n  mint inv() const { return pow(mod-2);}\r\n  mint& operator/=(const mint a) { return *this *= a.inv();}\r\n  mint operator/(const mint a) const { return mint(*this) /= a;}\r\n};\r\nistream& operator>>(istream& is, mint& a) { return is >> a.x;}\r\nostream& operator<<(ostream& os, const mint& a) { return os << a.x;}"
  },
  {
    "path": "mp.cpp",
    "content": "// Morris-Pratt\r\n// https://youtu.be/9MphwmIsO7Q?t=7283\r\ntemplate<typename T>\r\nstruct MP {\r\n  int n;\r\n  T t;\r\n  vector<int> a;\r\n  MP() {}\r\n  MP(const T& t): t(t) {\r\n    n = t.size();\r\n    a = vector<int>(n+1);\r\n    a[0] = -1;\r\n    int j = -1;\r\n    for (int i = 0; i < n; ++i) {\r\n      while (j != -1 && t[j] != t[i]) j = a[j];\r\n      j++;\r\n      a[i+1] = j;\r\n    }\r\n  }\r\n  int operator[](int i) { return a[i];}\r\n  vector<int> findAll(const T& s) {\r\n    vector<int> res;\r\n    int j = 0;\r\n    for (int i = 0; i < s.size(); ++i) {\r\n      while (j != -1 && t[j] != s[i]) j = a[j];\r\n      j++;\r\n      if (j == n) {\r\n        res.push_back(i-j+1);\r\n        j = a[j];\r\n      }\r\n    }\r\n    return res;\r\n  }\r\n};"
  },
  {
    "path": "perm.cpp",
    "content": "// Permutation\r\n// https://youtu.be/-j02o6__jgs?t=7302\r\nstruct Perm : vector<int> {\r\n#define n (int)(size())\r\n#define p (*this)\r\n  Perm(int _n): vector<int>(_n) {\r\n    iota(begin(), end(), 0);\r\n  }\r\n  template<class...Args> Perm(Args...args): vector<int>(args...) {}\r\n  Perm(initializer_list<int> a): vector<int>(a.begin(),a.end()) {}\r\n  Perm operator+(const Perm& a) const {\r\n    Perm r(n);\r\n    for (int i = 0; i < n; ++i) r[i] = p[a[i]];\r\n    return r;\r\n  }\r\n  Perm& operator+=(const Perm& a) {\r\n    return *this = (*this)+a;\r\n  }\r\n  Perm operator-() const {\r\n    Perm r(n);\r\n    for (int i = 0; i < n; ++i) r[p[i]] = i;\r\n    return r;\r\n  }\r\n  Perm operator-(const Perm& a) const {\r\n    return *this + -a;\r\n  }\r\n  Perm& operator-=(const Perm& a) {\r\n    return *this += -a;\r\n  }\r\n  // next permutation\r\n  bool operator++() {\r\n    return next_permutation(begin(),end());\r\n  }\r\n#undef n\r\n#undef p\r\n};"
  },
  {
    "path": "prime.cpp",
    "content": "// Sieve of Eratosthenes\r\n// https://youtu.be/UTVg7wzMWQc?t=2774\r\nstruct Sieve {\r\n  int n;\r\n  vector<int> f, primes;\r\n  Sieve(int n=1):n(n), f(n+1) {\r\n    f[0] = f[1] = -1;\r\n    for (ll i = 2; i <= n; ++i) {\r\n      if (f[i]) continue;\r\n      primes.push_back(i);\r\n      f[i] = i;\r\n      for (ll j = i*i; j <= n; j += i) {\r\n        if (!f[j]) f[j] = i;\r\n      }\r\n    }\r\n  }\r\n  bool isPrime(int x) { return f[x] == x;}\r\n  vector<int> factorList(int x) {\r\n    vector<int> res;\r\n    while (x != 1) {\r\n      res.push_back(f[x]);\r\n      x /= f[x];\r\n    }\r\n    return res;\r\n  }\r\n  vector<P> factor(int x) {\r\n    vector<int> fl = factorList(x);\r\n    if (fl.size() == 0) return {};\r\n    vector<P> res(1, P(fl[0], 0));\r\n    for (int p : fl) {\r\n      if (res.back().first == p) {\r\n        res.back().second++;\r\n      } else {\r\n        res.emplace_back(p, 1);\r\n      }\r\n    }\r\n    return res;\r\n  }\r\n  vector<pair<ll,int>> factor(ll x) {\r\n    vector<pair<ll,int>> res;\r\n    for (int p : primes) {\r\n      int y = 0;\r\n      while (x%p == 0) x /= p, ++y;\r\n      if (y != 0) res.emplace_back(p,y);\r\n    }\r\n    if (x != 1) res.emplace_back(x,1);\r\n    return res;\r\n  }\r\n};"
  },
  {
    "path": "rerooting.cpp",
    "content": "// Rerooting\r\n// https://youtu.be/zG1L4vYuGrg?t=7092\r\n// TODO: vertex info, edge info\r\nstruct Rerooting {\r\n  struct DP {\r\n    DP() {}\r\n    DP operator+(const DP& a) const {\r\n      // edit here\r\n    }\r\n    DP addRoot() const {\r\n      // edit here\r\n    }\r\n  };\r\n  \r\n  int n;\r\n  vector<vector<int>> to;\r\n  vector<vector<DP>> dp;\r\n  vector<DP> ans;\r\n  Rerooting(int n=0):n(n),to(n),dp(n),ans(n) {}\r\n  void addEdge(int a, int b) {\r\n    to[a].push_back(b);\r\n    to[b].push_back(a);\r\n  }\r\n  void init() {\r\n    dfs(0);\r\n    bfs(0);\r\n  }\r\n\r\n  DP dfs(int v, int p=-1) {\r\n    DP dpSum;\r\n    dp[v] = vector<DP>(to[v].size());\r\n    rep(i,to[v].size()) {\r\n      int u = to[v][i];\r\n      if (u == p) continue;\r\n      dp[v][i] = dfs(u,v);\r\n      dpSum = dpSum + dp[v][i];\r\n    }\r\n    return dpSum.addRoot();\r\n  }\r\n  void bfs(int v, const DP& dpP=DP(), int p=-1) {\r\n    int deg = to[v].size();\r\n    rep(i,deg) if (to[v][i] == p) dp[v][i] = dpP;\r\n\r\n    vector<DP> dpSumL(deg+1);\r\n    rep(i,deg) dpSumL[i+1] = dpSumL[i] + dp[v][i];\r\n    vector<DP> dpSumR(deg+1);\r\n    for (int i = deg-1; i >= 0; --i)\r\n      dpSumR[i] = dpSumR[i+1] + dp[v][i];\r\n    ans[v] = dpSumL[deg].addRoot();\r\n\r\n    rep(i,deg) {\r\n      int u = to[v][i];\r\n      if (u == p) continue;\r\n      DP d = dpSumL[i] + dpSumR[i+1];\r\n      bfs(u, d.addRoot(), v);\r\n    }\r\n  }\r\n};\r\n"
  },
  {
    "path": "template.cpp",
    "content": "#include <bits/stdc++.h>\r\nusing namespace std;\r\n#include <atcoder/all>\r\nusing namespace atcoder;\r\n#define rep(i,n) for (int i = 0; i < (n); ++i)\r\nusing ll = long long;\r\nusing P = pair<int,int>;\r\n\r\nint main() {\r\n  return 0;\r\n}"
  },
  {
    "path": "uf.cpp",
    "content": "// UnionFind\r\n// coding: https://youtu.be/TdR816rqc3s?t=726\r\n// comment: https://youtu.be/TdR816rqc3s?t=6822\r\nstruct UnionFind {\r\n  vector<int> d;\r\n  UnionFind(int n=0): d(n,-1) {}\r\n  int find(int x) {\r\n    if (d[x] < 0) return x;\r\n    return d[x] = find(d[x]);\r\n  }\r\n  bool unite(int x, int y) {\r\n    x = find(x); y = find(y);\r\n    if (x == y) return false;\r\n    if (d[x] > d[y]) swap(x,y);\r\n    d[x] += d[y];\r\n    d[y] = x;\r\n    return true;\r\n  }\r\n  bool same(int x, int y) { return find(x) == find(y);}\r\n  int size(int x) { return -d[find(x)];}\r\n};"
  },
  {
    "path": "z.cpp",
    "content": "// Z-algorithm\r\n// https://snuke.hatenablog.com/entry/2014/12/03/214243\r\n// https://youtu.be/Uqtxz1KTKOQ?t=9214\r\nstruct Z {\r\n  int n;\r\n  string s;\r\n  vector<int> z;\r\n  Z() {}\r\n  Z(const string& s): s(s) { init();}\r\n  void init() {\r\n    n = s.size();\r\n    z = vector<int>(n);\r\n    z[0] = n;\r\n    for (int i = 1, j = 0; i < n;) {\r\n      while (i+j < n && s[i+j] == s[j]) ++j;\r\n      z[i] = j;\r\n      if (j) {\r\n        int k = 1;\r\n        while (i+k < n && k+z[k] < j) {\r\n          z[i+k] = z[k];\r\n          k++;\r\n        }\r\n        i += k; j -= k;\r\n      } else i++;\r\n    }\r\n  }\r\n  int operator[](int i) const { return z[i];}\r\n};\r\n"
  }
]