library

This documentation is automatically generated by online-judge-tools/verification-helper

View the Project on GitHub maspypy/library

:heavy_check_mark: string/rollinghash_field.hpp

Verified with

Code

// +, -, * が定義された構造体を渡す
template <typename Field>
struct RollingHash_Field {
  using F = Field;
  const F base;
  vector<F> power;

  static inline F generate_base() { return RNG(1LL << 60); }

  inline void expand(int sz) {
    if (int(power.size()) < sz + 1) {
      int pre_sz = (int)power.size();
      power.resize(sz + 1);
      for (int i = pre_sz - 1; i < sz; i++) { power[i + 1] = power[i] * base; }
    }
  }

  explicit RollingHash_Field(F base = generate_base()) : base(base), power{1} {}

  template <typename STRING>
  vector<F> build(const STRING &s) const {
    int sz = s.size();
    vector<F> hashed(sz + 1);
    for (int i = 0; i < sz; i++) {
      hashed[i + 1] = (hashed[i] * base) + F(s[i]);
    }
    return hashed;
  }

  F query(const vector<F> &s, int l, int r) {
    expand(r - l);
    return s[r] - s[l] * power[r - l];
  }

  F combine(F h1, F h2, size_t h2len) {
    expand(h2len);
    return add(mul(h1, power[h2len]), h2);
  }

  int lcp(const vector<F> &a, int l1, int r1, const vector<F> &b, int l2,
          int r2) {
    int len = min(r1 - l1, r2 - l2);
    int low = 0, high = len + 1;
    while (high - low > 1) {
      int mid = (low + high) / 2;
      if (query(a, l1, l1 + mid) == query(b, l2, l2 + mid))
        low = mid;
      else
        high = mid;
    }
    return low;
  }
};
#line 1 "string/rollinghash_field.hpp"
// +, -, * が定義された構造体を渡す
template <typename Field>
struct RollingHash_Field {
  using F = Field;
  const F base;
  vector<F> power;

  static inline F generate_base() { return RNG(1LL << 60); }

  inline void expand(int sz) {
    if (int(power.size()) < sz + 1) {
      int pre_sz = (int)power.size();
      power.resize(sz + 1);
      for (int i = pre_sz - 1; i < sz; i++) { power[i + 1] = power[i] * base; }
    }
  }

  explicit RollingHash_Field(F base = generate_base()) : base(base), power{1} {}

  template <typename STRING>
  vector<F> build(const STRING &s) const {
    int sz = s.size();
    vector<F> hashed(sz + 1);
    for (int i = 0; i < sz; i++) {
      hashed[i + 1] = (hashed[i] * base) + F(s[i]);
    }
    return hashed;
  }

  F query(const vector<F> &s, int l, int r) {
    expand(r - l);
    return s[r] - s[l] * power[r - l];
  }

  F combine(F h1, F h2, size_t h2len) {
    expand(h2len);
    return add(mul(h1, power[h2len]), h2);
  }

  int lcp(const vector<F> &a, int l1, int r1, const vector<F> &b, int l2,
          int r2) {
    int len = min(r1 - l1, r2 - l2);
    int low = 0, high = len + 1;
    while (high - low > 1) {
      int mid = (low + high) / 2;
      if (query(a, l1, l1 + mid) == query(b, l2, l2 + mid))
        low = mid;
      else
        high = mid;
    }
    return low;
  }
};
Back to top page