LuoguP3121 [USACO15FEB]审查(黄金)Censoring (Gold)Hash做法By cellur925
Posted nopartyfoucaodong
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LuoguP3121 [USACO15FEB]审查(黄金)Censoring (Gold)Hash做法By cellur925相关的知识,希望对你有一定的参考价值。
其实这题正解是AC自动机的,字符串哈希吸氧才能过的,但是我太菜了不会...只能先用哈希苟了。
在扫描单词的时候首先把各个单词的哈希值和长度存起来。然后按照长度从小到大将各单词排序。而那个长长的字符串呢,我们就把它一点一点往栈里塞,够最小长度单词的长度时,我们就比较下,这样反复下去。如果遇到相同的字符串,就把他们弹出。
这个思路最巧妙的一点感觉就是用栈了。我自己写哈希的时候遇到删除的情况就布吉岛怎么搞了qwq。
这里的哈希值不能预处理出来的,而是动态维护的。因为有可能会删掉子串。所以只需要预处理出p数组(131的乘方),然后动态求哈希值。
Code
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<iostream> 5 6 using namespace std; 7 typedef unsigned long long ull; 8 9 int lenall,top,n; 10 char sta[100090],tmp[100090],s[100090]; 11 ull b=131,f[100090],p[100090]; 12 struct dictionary{ 13 int len; 14 ull has; 15 }t[2000]; 16 17 bool cmp(dictionary a,dictionary b) 18 { 19 return a.len<b.len; 20 } 21 22 ull gethash(int l,int r) 23 { 24 return f[r]-f[l-1]*p[r-l+1]; 25 } 26 27 int main() 28 { 29 scanf("%s",sta+1); 30 p[0]=1; 31 lenall=strlen(sta+1); 32 scanf("%d",&n); 33 for(int i=1;i<=n;i++) 34 { 35 scanf("%s",tmp+1); 36 t[i].len=strlen(tmp+1); 37 for(int j=1;j<=t[i].len;j++) 38 t[i].has=t[i].has*b+(tmp[j]-‘a‘+1); 39 } 40 sort(t+1,t+1+n,cmp); 41 for(int i=1;i<=lenall;i++) 42 p[i]=p[i-1]*b; 43 for(int i=1;i<=lenall;i++) 44 { 45 s[++top]=sta[i]; 46 f[top]=f[top-1]*b+s[top]; 47 while(top<t[1].len&&i<lenall) 48 s[++top]=sta[++i],f[top]=f[top-1]*b+s[top]; 49 for(int j=1;j<=n&⊤j++) 50 if(top-t[j].len+1>=1&&t[j].has==gethash(top-t[j].len+1,top)) 51 top-=t[j].len; 52 } 53 for(int i=1;i<=top;i++) 54 cout<<s[i]; 55 cout<<endl; 56 return 0; 57 }
以上是关于LuoguP3121 [USACO15FEB]审查(黄金)Censoring (Gold)Hash做法By cellur925的主要内容,如果未能解决你的问题,请参考以下文章
Luogu P3121 [USACO15FEB]审查(黄金)Censoring (Gold)
luogu_P3121 [USACO15FEB]审查(黄金)Censoring (Gold)
P3121 [USACO15FEB]审查(黄金)Censoring (Gold)
洛谷 P3121 [USACO15FEB]审查(黄金)Censoring (Gold) AC自动机+栈