給定字典 {W_i},長字符串 S(|S|≤1e5)。支持兩操作:
Q L R:查詢 S[L..R] 是否在字典中。
C X Y:將 S[X] 改為字符 Y。
多測試用例,字典總長 ≤ 2e6,操作數 ≤ 1e5。
字符串哈希:`H[i] = H[i-1]*seed + (s[i]-'a'+1)`,`seed=31`,用 `unsigned long long` 自然溢出模 2^64。
線段樹節點存儲區間哈希值,合併:`hash = left.hash * pow[right.len] + right.hash`。
單點更新 O(log n),區間查詢哈希 O(log n)。
讀入所有字典詞,計算其哈希值存入 `unordered_set
struct Node { int l,r; ULL hash; } tree[4*MAXN];
ULL powBase[MAXN]; // seed^i
void build(int l,int r,int rt) { ... }
void update(int pos,char val,int rt) { ... }
ULL query(int L,int R,int rt) { ... }
預處理字典 O(總長)。每操作 O(log |S|),總 O((|S|+Q) log |S|),極易通過。
經典「字符串哈希 + 線段樹」模板題,將動態子串哈希查詢轉化為區間哈希合併,配合字典哈希集合 O(1) 判斷,代碼結構清晰,是字符串動態問題必會技巧。