Question: There are 10000 pattern strings and a matching string with a length of 100000. There are two operations:
1. query whether the substring [L, R] of the matching string exists in the pattern string.
2. Modify the character at a certain position in the matching string
Solution: Because the RK function satisfies the range addition, you can use the line segment tree to dynamically maintain and query the hash value of a substring to obtain the hash value of the substring, the rest is the normal rk.
Place the hash values of all mode strings in map. If the hash values of the mode strings with the same hash values are connected in a linked list, when the hash value of a sub-string is obtained, first, check whether the map exists. If it exists, compare it with the pattern string on the hash value linked list.
import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.StreamTokenizer;import java.util.Arrays;import java.util.TreeMap;public class FZU2045ac {long mod = 100000007;int maxn = 100010;long pow(long x, int p) {long ans = 1;while (p > 0) {if ((p & 1) == 1)ans = (ans * x) % mod;p >>= 1;x = (x * x) % mod;}return ans;}class SegTree {class node {int left, right;long hash;node(int l, int r) {left = l;right = r;}int length() {return right - left + 1;}int mid() {return (left + right) >> 1;}}node tree[] = new node[maxn << 2];void init(int idx, int l, int r, int arr[]) {tree[idx] = new node(l, r);if (l == r) {tree[idx].hash = arr[r];return;}int m = tree[idx].mid();init(idx << 1, l, m, arr);init(idx << 1 | 1, m + 1,r, arr);pushup(idx);}void pushup(int idx) {if (tree[idx].left == tree[idx].right)return;tree[idx].hash = (tree[idx<<1].hash* pow(26, tree[idx<<1|1].length())+tree[idx<< 1|1].hash)% mod;}long query(int idx, int left, int right) {if (tree[idx].left==left&&tree[idx].right== right)return tree[idx].hash;int m = tree[idx].mid();if (right<=m)return query(idx << 1, left, right);if (left>m)return query(idx << 1 | 1, left, right);long x = query(idx << 1, left, m);long y = query(idx << 1 | 1, m + 1, right);return (x*pow(26,right-m)+y) % mod;}void update(int idx, int pos, long val) {if (tree[idx].left == pos && tree[idx].right == pos) {tree[idx].hash = val;return;}int m = tree[idx].mid();if (m >= pos)update(idx<<1,pos,val);elseupdate(idx<<1|1,pos,val);pushup(idx);}}String ss[] = new String[10010];int nxt[] = new int[10010], pre[] = new int[10010];TreeMap<Long, Integer> mp = new TreeMap<Long, Integer>();void build() throws IOException {int n = nextInt();Arrays.fill(nxt, -1);Arrays.fill(pre, -1);mp.clear();for (int i = 1; i <= n; i++) {ss[i] = next();int len = ss[i].length();long hash = 0;for (int j = 0; j < len; j++)hash = (hash * 26 + (ss[i].charAt(j) - 'a')) % mod;if (mp.containsKey(hash)) {int temp = mp.get(hash);pre[i] = temp;nxt[temp] = i;}mp.put(hash, i);}}boolean test(int l, int r) {long hash = st.query(1, l, r);if (!mp.containsKey(hash))return false;int p = mp.get(hash);while (pre[p] != -1)p = pre[p];while (p != -1) {if (r - l + 1 == ss[p].length()){boolean flag = true;for (int i = 0; i < r - l + 1; i++)if (ss[p].charAt(i) - 'a' != arr[l + i]) {flag = false;break;}if (flag)return true;}p = nxt[p];}return false;}int arr[] = new int[maxn];SegTree st = new SegTree();void run() throws IOException {int cas = nextInt();for (int c = 1; c <= cas; c++) {System.out.println("Case #"+c+":");build();String s = next();int cnt = s.length();for (int i = 1; i <= cnt; i++)arr[i] = s.charAt(i - 1) - 'a';st.init(1, 1, cnt, arr);int m = nextInt();while (m-- > 0) {String op = next();if (op.charAt(0) == 'Q')if (test(nextInt()+1, nextInt()+1))System.out.println("Yes");elseSystem.out.println("No");else {int p = nextInt()+1;int val = next().charAt(0) - 'a';st.update(1, p, val);arr[p] = val;}}}}StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));int nextInt() throws IOException {in.nextToken();return (int) in.nval;}String next() throws IOException {in.nextToken();return in.sval;}public static void main(String[] args) throws IOException {new FZU2045ac().run();}}