http://acm.hdu.edu.cn/showproblem.php?pid=3973
Problem descriptionyou is given some words {Wi}. Then our stupid AC would give you a very long string S. AC was stupid and always wants to know whether one substring from S exists in the given words {Wi}.
For example, S = "ABCD", and the given words {Wi} = {"BC", "ad", "DD"}. Then only s[2..3] = "BC" exists in the given words. (In this problem, the first element of the S have the index "0".)
However, this was toooooooooooo easy for acmers! The stupid and evil AC would now change some letters in S. So could your solve this problem now?
Inputthe first line is one integer T indicates the number of the the the Test cases. (T <=20)
Then for every case, there was one integer n in the first line indicates the number of the given words (the size of the {Wi} ) . Then n lines have one string which only have ' a '-' Z '. (1 <= N <= 10000, sigma| wi| <= 2000000).
Then one line have one string S, here | s| <= 100000.
Then one integer m, indicating the number of operations. (1 <= m <= 100000)
Then M lines, the operation:
(1) Q L R, tell AC whether the s[l. R] exists in the given strings;
(2) C X Y, Chang S[x] to Y, here y: ' a '-' Z '.
Outputfirst output "case #idx: ' In a ', ' here idx ' is the ' case ' number count from 1.Then for each" Q "operation, OU Tput "Yes" if s[l. R] exists in the given strings, otherwise output "No".
Sample Input
12ab IOC Ipcad 6 q 0 2 Q 3 4 C 1 o C 4 B Q 0 2 Q 3 4
Sample Output
Case #1: NoNo Yes Yes
/**hdu 3973 Segment Tree single-point update interval Evaluation + string Hash topic: Given a number of strings, and then given a large string, the string of single-point update and interval query, The interval substring of a query is not a problem in a known string: The string is hashed using a segment tree to update, and the hash value of the string is stored with set. As to how the hash and the idea of great white books is almost just the prefix represented here */#include <stdio.h> #include <string.h> #include <iostream> #include <set>using namespace Std;const int maxn=100010;const int seed=31;typedef unsigned long long ll;struct note{int L , R; LL hashes;} Tree[maxn*4];char str[2000100]; LL hash[maxn];int n;void init () {hash[0]=1; for (int i=1;i<maxn;i++) {hash[i]=hash[i-1]*seed; }}ll Get_hash () {int len=strlen (str); LL sum=0; for (int i=0;i<len;i++) sum=sum*seed+str[i]-' a ' +1; return sum;} void build (int l,int r,int root) {tree[root].l=l; Tree[root].r=r; if (l==r) {tree[root].hashes=str[l]-' a ' +1; Return } int mid= (L+R)/2; Build (l,mid,root<<1); Build (mid+1,r,root<<1|1); Tree[root].hashes=tree[root<<1].hashes*hash[r-mid]+tree[root<<1|1].hashes;} void Update (INT L,int root) {if (TREE[ROOT].L==TREE[ROOT].R) {tree[root].hashes=str[l]-' a ' +1; Return } int mid= (TREE[ROOT].L+TREE[ROOT].R) >>1; if (l<=mid) update (L,ROOT<<1); else update (L,ROOT<<1|1); Tree[root].hashes=tree[root<<1].hashes*hash[tree[root].r-mid]+tree[root<<1|1].hashes;} LL query (int l,int r,int root) {//printf ("**\n"); if (tree[root].l==l&&tree[root].r==r) return tree[root].hashes; int mid= (TREE[ROOT].R+TREE[ROOT].L) >>1; if (r<=mid) return query (l,r,root<<1); else if (l>mid) return query (L,R,ROOT<<1|1); return query (l,mid,root<<1) *hash[r-mid]+query (mid+1,r,root<<1|1);} int main () {int t,tt=0; Init (); scanf ("%d", &t); while (t--) {printf ("Case #%d:\n", ++TT); scanf ("%d", &n); set<ll>mp; for (int i=0;i<n;i++) {scanf ("%s", str); Mp.insert (Get_hash ()); } scanf ("%s", str); int Len=strlen (str); Build (0,len-1,1); int q; scanf ("%d", &q); for (int i=1;i<=q;i++) {char c[5]; scanf ("%s", c); if (c[0]== ' C ') {int A; Char b[10]; scanf ("%d%s", &a,b); STR[A]=B[0]; Update (a,1); } else {int l,r; scanf ("%d%d", &l,&r); if (Mp.find (query (l,r,1))!=mp.end ()) printf ("yes\n"); else printf ("no\n"); }}} return 0;}
Hdu 3973 string hash+ segment Tree