Problem Description You are given some words {Wi}. Then our stupid AC will give you a very long string S. AC is stupid and always wants to know whether one substring from S exists in the given words {Wi} .
1 2 ab ioc ipcad 6 Q 0 2 Q 3 4 C 1 o C 4 b Q 0 2 Q 3 4
Case #1: No No Yes Yes
/** hdu 3973 線段樹單點更新區間求值+字符串hash 題目大意:給定多個字符串,然後給定一個大串,對該串進行單點更新和區間查詢,查詢的區間子串是不是在已知的字符串中出現 解題思路:對字符串進行hash處理采用線段樹來進行更新,用set存放字符串的哈希值。至於怎麼哈希和大白書上的思路差不多只是這裡是表示的前綴 */ #include#include #include #include 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 >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(** ); 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: ,++tt); scanf(%d,&n); set mp; for(int i=0;i