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&&top;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 }

 

原文地址:https://www.cnblogs.com/nopartyfoucaodong/p/9768507.html

时间: 2024-10-09 05:43:51

LuoguP3121 [USACO15FEB]审查(黄金)Censoring (Gold)【Hash做法】By cellur925的相关文章

洛谷 P3121 [USACO15FEB]审查(黄金)Censoring (Gold) 【AC自动机+栈】

这个和bzoj同名题不一样,有多个匹配串 但是思路是一样的,写个AC自动机,同样是开两个栈,一个存字符,一个存当前点在trie树上的位置,然后如果到了某个匹配串的末尾,则弹栈 #include<iostream> #include<cstdio> #include<cstring> #include<queue> using namespace std; const int N=100005; int n,t[N],top; char a[N],b[N],s

P3121 [USACO15FEB]审查(黄金)Censoring (Gold)

吐槽 数据太水了吧,我AC自动机的trie建错了结果只是RE了两个点,还以为数组开小了改了好久 思路 看到多模板串,字符串匹配,且模板串总长度不长,就想到AC自动机 然后用栈维护当前的字符串位置,如果匹配到了,就从栈里逐个弹出对应的字符,并且回溯到匹配这个单词之前的节点 s每个字符最多会被出栈和入栈各两次,复杂度是\(O(n+m)\)的 代码 #include <cstdio> #include <algorithm> #include <cstring> #inclu

luogu_P3121 [USACO15FEB]审查(黄金)Censoring (Gold)

栈模拟,哈希 #include<iostream> #include<cstdio> #define ri register int #define u unsigned long long namespace opt { inline u in() { u x(0),f(1); char s(getchar()); while(s<'0'||s>'9') { if(s=='-') f=-1; s=getchar(); } while(s>='0'&&am

「USACO15FEB」Censoring (Silver) 审查(银) 解题报告

题面 就是让你--在字符串A中,如果字符串B是A的子串,那么就删除在A中第一个出现的B,然后拼接在一起,一直重复上述步骤直到B不再是A的子串 |A|\(\le 10^6\) 思路: KMP+栈 1.由于是两个字符串匹配的问题,当然一下子就会想到KMP 2.由于是删去一段区间,很多人第一反应会想到链表,但是在这里,其实删除了一段后,对之前是没有影响的,并且,一定是从后往前删除,所以,更优的存储结构应该是栈. 3.有人会问,为什么删去对前面没有影响,这就根据KMP的原理,做到i这个位置的结果就是最优

hdu 5172(线段树||HASH)

GTY's gay friends Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1379    Accepted Submission(s): 355 Problem Description GTY has n gay friends. To manage them conveniently, every morning he ord

AC自动机总结

AC自动机总结 自动机的概念: 自动机又称有限状态机,是从初始状态不断接受输入,根据输入数据和当前状态跳转到下一状态的一种机器. AC自动机可以实现多串匹配单串.复杂度是\(O(n+m)\),也就是匹配串长+模式串总长. AC自动机匹配失配时,类似KMP算法的next数组,AC自动机上有fail指针可以跳到下一个应该进行匹配的状态. fail指针的一般定义是:沿着父亲的fail指针一直向上跳,直到跳到某一个节点,这个节点拥有与自己相同字母的子节点,那么fail指针就指向这个相同字母的子节点. 一

NOI2017 划水记

Day-2 听说我能来NOI(捂脸熊 xy说我肩负重任(奶的漂亮),要MAKE XJ GREAT AGAIN (大雾 感觉我已经沦为暴力隔膜选手了啊…… Day-1 报到日 早上开super meat boy,把第5张图推的差不多了…… 然而我并没有把它拷出来,绍兴一中网络太慢……惨惨啊…… 没办法,只能玩玩pvz了咯……(八炮真好操- 本来想开斗地主的,然而并没有带牌,而且地点偏僻,并不能饿了么 好吧,只能人生相谈了(误 吴老板说他如果有超过30分的单纯形部分分就女装 cbh谈写博客被查表 x

nullcon HackIM 2016 -- Programming Question 2

Your simple good Deeds can save you but your GREED can kill you. This has happened before. This greedy person lived a miserable life just for the greed of gold and lust. You must know him, once you know him, you must reach his capital and next clues

优化MySQL,还是使用缓存?读一篇文章有感

今天我想对一个Greenfield项目上可以采用的各种性能优化策略作个对比.换言之,该项目没有之前决策强加给它的各种约束限制,也还没有被优化过. 具体来说,我想比较的两种优化策略是优化MySQL和缓存.提前指出,这些优化是正交的,唯一让你选择其中一者而不是另一者的原因是他们都耗费了资源,即开发时间. 优化MySQL 优化MySQL时,一般会先查看发送给mysql的查询语句,然后运行explain命令.稍加审查后很常见的做法是增加索引或者对模式做一些调整. 优点 1.一个经过优化的查询对于所有使用