字符串Hash模板

/*
使用前先调用 : H.init() 
读入 : H.read()
获得 [l, r] 的hash值: H.get(l,r)
(范围是unsigned long long, 要统计请使用map<unsigned long long, int>)
判断两个子串是否相等 : H.equals(l1, r1, l2, r2)
访问字符串第i个元素 : H[i] 
*/
const int H_N = 1e6+10;
const int H_P = 131;
int H_len;
struct string_Hash{
  char s[H_N];
  unsigned long long f[H_N], p[H_N];
  void init() {
    p[0] = 1;
    for (int i = 1; i < H_N; i++) {
      p[i] = p[i-1] * H_P;
    }
  }
  void read() {
    scanf("%s",s+1);
    H_len = strlen(s+1);
    p[0] = 1, f[0] = 0;
    for (int i = 1; i <= H_len; i++) {
      f[i] = f[i-1] * H_P + s[i];
    }
  }
  inline unsigned long long get(int l = 1, int r = H_len) {
    return f[r] - f[l-1] * p[r-l+1];
  }
  bool equals(int l1, int r1, int l2, int r2) {
    return get(l1, r1) == get(l2, r2);
  }
  inline int size() {
    return H_len;
  }
  inline int length() {
    return H_len;
  }
  inline char front() {
    return s[1];
  }
  inline char back() {
    return s[H_len];
  }
  inline char *begin() {
    return s+1;
  }
  inline char *end() {
    return s+H_len;
  }
  inline char *string() {
    return s+1;
  }
  inline void push_back(char ch) {
    s[++H_len] = ch;
    f[H_len] = f[H_len-1] * H_P + ch;
  }
  inline void append(char ch) {
    s[++H_len] = ch;
    f[H_len] = f[H_len-1] * H_P + ch;
  }
  inline void push_back(char str[]) {
    int length = strlen(str);
    for (int i = 0; i < length; i++) {
      s[++H_len] = str[i];
      f[H_len] = f[H_len-1] * H_P + str[i];
    }
  }
  inline void append(char str[]) {
    int length = strlen(str);
    for (int i = 0; i < length; i++) {
      s[++H_len] = str[i];
      f[H_len] = f[H_len-1] * H_P + str[i];
    }
  }
  char operator [] (int idx) {
    return s[idx];
  }
}H;

 

posted @ 2020-07-23 20:18  Kimyon  阅读(157)  评论(0编辑  收藏  举报