我的模板

Strings

Hash

template < int N >
struct PolyHashing {
  i64 s[N];
  i64 mod[2] = {1610612741ll, 805306457ll};
  i64 pw[N][2];
  i64 w[N][2];
  void init (int m) {
    pw[0][0] = pw[0][1] = 1;
    for (int i = 1;i <= m; ++ i) {
      pw[i][0] = pw[i - 1][0] * 233ll % mod[0];
      pw[i][1] = pw[i - 1][1] * 233ll % mod[1];
    }
    w[0][0] = w[0][1] = 0;
    for (int i = 1;i <= m; ++ i) {
      i64 Z = (i64) s[i];
      w[i][0] = (w[i - 1][0] * 233ll + Z) % mod[0];
      w[i][1] = (w[i - 1][1] * 233ll + Z) % mod[1];
    }
    return ;
  }
  i64 query (int l, int r, int v) {return (w[r][v] + mod[v] - (w[l - 1][v] * pw[r - l + 1][v] % mod[v])) % mod[v];}
  std :: pair < i64, i64 > val (int l, int r) {return std :: make_pair (query (l, r, 0), query (l, r, 1));}
};

SA

template < int N, int M >
struct SA {
  int str[N], n;
  bool empty () {return (n == 0);}
  int size () {return n;}
  void clear () {n = 0; return ;}
  void pushchar (int ch) {
    str[++ n] = ch; 
    return ;
  }
  void popchar () {
    assert (!empty ());
    n --;
    return ;
  }
  int st[N][M], lg[N];
  int rk[N << 1], sa[N], tmp[N << 1], height[N];
  void init () {
    if (n == 1) {
      rk[1] = sa[1] = 1;
      height[1] = 0;
      lg[0] = -1, lg[1] = 0;
      st[1][0] = height[1];
      return ;
    }
    for (int i = 1;i <= n; ++ i) rk[i] = str[i], sa[i] = i;
    for (int w = 1; w < n; w <<= 1) {
      auto f = [&] (int x) -> std :: pair < int, int > {
        return std :: make_pair (rk[x], rk[x + w]);
      };
      auto g = [&] (int x, int y) -> bool {
        return f (x) < f (y);
      };
      std :: sort (sa + 1, sa + 1 + n, g);
      int p = 1;
      tmp[sa[1]] = 1;
      for (int i = 2;i <= n; ++ i) {
        p += (f (sa[i]) != f (sa[i - 1]));
        tmp[sa[i]] = p;
      }
      for (int i = 1;i <= n; ++ i) rk[i] = tmp[i];
    }
    for (int i = 1, p = 0;i <= n; ++ i) {
      if (p > 0) p --;
      while (str[i + p] == str[sa[rk[i] - 1] + p]) p ++;
      height[rk[i]] = p;
    }
    for (int i = 1;i <= n; ++ i) st[i][0] = height[i];
    for (int j = 1;j < M; ++ j) {
      for (int i = 1;i + (1 << j) - 1 <= n; ++ i) {
        st[i][j] = std :: min (st[i][j - 1], st[i + (1 << (j - 1))][j - 1]);
      }
    }
    lg[0] = -1;
    for (int i = 1;i <= n; ++ i) lg[i] = lg[i >> 1] + 1;
    return ;
  }
  int LCPsuf (int x, int y) {
    if (x == y) return n - x + 1;
    x = rk[x], y = rk[y];
    if (x > y) std :: swap (x, y);
    x ++;
    int k = lg[y - x + 1];
    return std :: min (st[x][k], st[y - (1 << k) + 1][k]);
  }
  int LCP (int l, int r, int x, int y) {
    return std :: min ({LCPsuf (l, x), r - l + 1, y - x + 1});
  }
};
posted @ 2024-02-22 19:57  CountingGroup  阅读(15)  评论(0编辑  收藏  举报