CENSORING
CENSORING
题目描述
FJ为它的奶牛订阅了很多杂志,balabala.......,其中有一些奶牛不宜的东西(比如如何煮牛排)。
FJ将杂志中所有的文章提取出来组成一个长度最多为10^5的字符串S。他有一个要从S中删除的词语的列表,t1,t2...tn。
FJ每次找到最早的出现在列表里的子串,然后将其删去。他重复此过程,直到找不到这样的子串。值得注意的是删除一个单词可能产生一个新的之前并没有出现过的要被删除的单词。
FJ保证列表中没有一个字符串是另一个字符串的子串。要就是说每次要删的单词是唯一确定的。
帮助FJ确定最终S的删减版。
Solution
考虑把T建成AC自动机。把S扔进去匹配,,用栈记录每一步的位置,遇到可匹配点就往后跳到匹配该串前的位置。

1 #include<cstdio> 2 #include<iostream> 3 #include<cstdlib> 4 #include<cstring> 5 #include<algorithm> 6 #include<cmath> 7 #include<queue> 8 #define maxn 300050 9 using namespace std; 10 int n,len,tot,top; 11 int tr[maxn][28],fail[maxn],p[maxn]; 12 char s[maxn],ch[maxn]; 13 int zh[maxn];char ans[maxn]; 14 void ins(){ 15 int len=strlen(ch),k=0; 16 for(int i=0;i<len;i++){ 17 if(!tr[k][ch[i]-'a'])tr[k][ch[i]-'a']=++tot; 18 k=tr[k][ch[i]-'a']; 19 } 20 p[k]=len; 21 } 22 void build(){ 23 queue<int>q; 24 for(int i=0;i<26;i++)if(tr[0][i])q.push(tr[0][i]); 25 while(!q.empty()){ 26 int k=q.front();q.pop(); 27 for(int i=0;i<26;i++){ 28 if(tr[k][i]){ 29 fail[tr[k][i]]=tr[fail[k]][i]; 30 q.push(tr[k][i]); 31 } 32 else tr[k][i]=tr[fail[k]][i]; 33 } 34 } 35 } 36 int main() 37 { 38 scanf("%s",s); 39 cin>>n; 40 for(int i=1;i<=n;i++){ 41 scanf("%s",ch); 42 ins(); 43 } 44 build(); 45 n=strlen(s);int k=0; 46 for(int i=0;i<n;i++){ 47 k=tr[k][s[i]-'a']; 48 zh[++top]=k;ans[top]=s[i]; 49 if(p[k]){ 50 top-=p[k];k=zh[top]; 51 } 52 } 53 for(int i=1;i<=top;i++)printf("%c",ans[i]); 54 return 0; 55 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构