题目链接:点击打开链接
题意:给出一个原串和n个询问串,然后m个操作,询问分两种:
1:把x位置的字母改变;2:询问[x,y]之间的字符串是不是等于某个询问串。
先把每一个询问串的哈希值存到map里面,然后用线段树维护每一个区间的字符串的哈希
值,如果需要的串包含左右两个区间,就把右边区间求出的哈希值进左边区间的长度位。
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <vector>
#include <map>
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 <ull, int> 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
*/