/* 使用前先调用 : 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;