题目链接:点击打开链接
题意:给出一个原串和n个询问串,然后m个操作,询问分两种:
1:把x位置的字母改变;2:询问[x,y]之间的字符串是不是等于某个询问串。
先把每一个询问串的哈希值存到map里面,然后用线段树维护每一个区间的字符串的哈希
值,如果需要的串包含左右两个区间,就把右边区间求出的哈希值进左边区间的长度位。
#include #include #include #include #include #include #include using namespace std; #define maxn 111111 #define pl c<<1 #define pr (c<<1)|1 #define lson tree[c].l,tree[c].mid,pl #define rson tree[c].mid+1,tree[c].r,pr typedef unsigned long long ull; #define pow Pow #define hash Hash #define seed 131 struct node { int l, r, mid; ull num; } tree[maxn<<4]; map mp; int m, n, q; char a[2111111]; ull pow[2111111]; ull f (char a) { return a-'a'+1; } void push_up (int c) { if (tree[c].l == tree[c].r) return ; tree[c].num = tree[pl].num + tree[pr].num * pow[tree[pl].r-tree[pl].l+1]; return ; } void build_tree (int l, int r, int c) { tree[c].l = l, tree[c].r = r, tree[c].mid = (l+r)/2; if (l == r) { tree[c].num = f (a[l]); return ; } build_tree (lson); build_tree (rson); push_up (c); } void update (int l, int r, int c, int pos, int num) { if (l == r) { tree[c].num = num; return ; } if (tree[c].mid >= pos) update (lson, pos, num); else update (rson, pos, num); push_up (c); } ull query (int l, int r, int c, int x, int y) { if (x > y) return 0; if (l == x && y == r) { return tree[c].num; } if (tree[c].mid >= x) { return query (lson, x, tree[c].mid) + query (rson, tree[c].mid+1, y) * pow[tree[pl].r-x+1]; } else { return query (rson, x, y); } } void debug (int c) { cout << tree[c].l << " " << tree[c].r << " " << tree[c].num << endl; if (tree[c].l == tree[c].r) return ; debug (pl); debug (pr); } int main () { pow[0] = 1; for (int i = 1; i <= 2000000; i++) { pow[i] = pow[i-1]*seed; } int t, kase = 0; scanf ("%d", &t); while (t--) { printf ("Case #%d:\n", ++kase); mp.clear (); scanf ("%d", &m); for (int i = 0; i < m; i++) { ull hash = 0; scanf ("%s", a); n = strlen (a); for (int i = n-1; i >= 0; i--) { hash = hash*seed+f(a[i]); } mp[hash] = 1; } scanf ("%s", a+1); a[0] = '0'; n = strlen (a); n--; build_tree (1, n, 1); //debug (1); scanf ("%d", &q); char op[22]; int l, r; char change[22]; while (q--) { scanf ("%s", op); if (op[0] == 'Q') { scanf ("%d%d", &l, &r); l++, r++; ull ans_l = query (1, n, 1, l, n); ull ans_r = query (1, n, 1, r+1, n); ull ans = ans_l - ans_r*pow[r-l+1]; if (mp.count (ans)) { printf ("Yes\n"); } else printf ("No\n"); } else if (op[0] == 'C') { scanf ("%d%s", &l, change); l++; update (1, n, 1, l, f (change[0])); } } } return 0; } /* 1 5 z zz zzz cd fuck asdfghjkl 11 C 5 u C 6 c Q 4 7 C 4 f Q 4 7 C 1 z Q 0 1 Q 1 1 C 2 z Q 0 2 Q 1 2 */