[AC自己主动机] zoj Searching the String
意甲冠军:
到原始字符串。给n字符串,每个字符串都有一个属性,属性0代表重叠,1代表不能重叠
请各多少次出现的字符串
思维:
为了便于建立两台机器自己主动(0一个。1一个)
然后,它可以重叠非常好做,谁做
不可重叠的话须要记录两个东西
len[i]代表每一个串的长度,used[i]代表每一个串在之前出现的位置,初始化-1
然后遍历到的时候对于当前位置 j。 必须j>=used[i]+len[i] 才干算出现。而且更新
须要注意的是:
会出现相同属性而且相同的串。
我处理的方式就是排序。按id排序大的在前
然后算一遍大的,用大的赋值给id 小的且串同样的。
代码:
#include"cstdlib"
#include"cstdio"
#include"cstring"
#include"cmath"
#include"queue"
#include"algorithm"
#include"iostream"
using namespace std;
char fuck[123456];
int ans[123456],used[123456],len[123456];
struct word
{
int x,id;
char y[7];
} dc[123456];
struct trie
{
int mark;
trie *next[27];
trie *fail;
trie()
{
mark=0;
memset(next,0,sizeof(next));
fail=NULL;
}
};
trie *root0,*root1;
void init(int key,char *v,int id)
{
trie *p;
if(key) p=root1;
else p=root0;
for(int i=0; v[i]; i++)
{
int tep=v[i]-'a';
if(p->next[tep]==NULL) p->next[tep]=new trie();
p=p->next[tep];
}
p->mark=id;
}
void del(trie *p)
{
for(int j=0; j<26; j++) if(p->next[j]!=NULL) del(p->next[j]);
free(p);
}
void getac()
{
queue<trie*>q;
q.push(root0);
while(!q.empty())
{
trie *p,*tep;
p=q.front();
q.pop();
for(int i=0; i<26; i++)
{
if(p->next[i]!=NULL)
{
if(p==root0) p->next[i]->fail=root0;
else
{
tep=p->fail;
while(tep!=NULL)
{
if(tep->next[i]!=NULL)
{
p->next[i]->fail=tep->next[i];
break;
}
tep=tep->fail;
}
if(tep==NULL) p->next[i]->fail=root0;
}
q.push(p->next[i]);
}
}
}
q.push(root1);
while(!q.empty())
{
trie *p,*tep;
p=q.front();
q.pop();
for(int i=0; i<26; i++)
{
if(p->next[i]!=NULL)
{
if(p==root1) p->next[i]->fail=root1;
else
{
tep=p->fail;
while(tep!=NULL)
{
if(tep->next[i]!=NULL)
{
p->next[i]->fail=tep->next[i];
break;
}
tep=tep->fail;
}
if(tep==NULL) p->next[i]->fail=root1;
}
q.push(p->next[i]);
}
}
}
}
void finde(char *v)
{
trie *p0=root0,*p1=root1;
for(int i=0; v[i]; i++)
{
int tep=v[i]-'a';
while(p0->next[tep]==NULL && p0!=root0)
p0=p0->fail;
p0=p0->next[tep];
if(p0==NULL) p0=root0;
trie *q0=p0;
while(q0!=root0)
{
if(q0->mark!=0) ans[q0->mark]++;
q0=q0->fail;
}
while(p1->next[tep]==NULL && p1!=root1)
p1=p1->fail;
p1=p1->next[tep];
if(p1==NULL) p1=root1;
trie *q1=p1;
while(q1!=root1)
{
if(q1->mark!=0)
{
if(i>=used[q1->mark]+len[q1->mark]) //不可重叠的推断
{
ans[q1->mark]++;
used[q1->mark]=i;
}
}
q1=q1->fail;
}
}
}
int cmp(word a,word b) //排序的cmp
{
if(a.x==b.x)
{
if(strcmp(a.y,b.y)==0)
{
if(a.id>b.id) return 1;
else return 0;
}
else
{
if(strcmp(a.y,b.y)>0) return 1;
else return 0;
}
}
else
{
if(a.x>b.x) return 1;
else return 0;
}
}
int main()
{
int cas=1;
while(scanf("%s",fuck)!=-1)
{
int n;
scanf("%d",&n);
root0=new trie();
root1=new trie();
for(int i=1; i<=n; i++)
{
int x;
char y[12];
scanf("%d%s",&x,y);
len[i]=strlen(y);
init(x,y,i);
dc[i].x=x;
strcpy(dc[i].y,y);
dc[i].id=i;
}
memset(ans,0,sizeof(ans));
memset(used,-1,sizeof(used));
getac();
finde(fuck);
sort(dc+1,dc+1+n,cmp);
int i;
for(i=1; dc[i+1].x==1; i++) //赋值给那些反复的
{
if(strcmp(dc[i].y,dc[i+1].y)==0)
ans[dc[i+1].id]=ans[dc[i].id];
}
for(i=i+1; i<n; i++)
{
if(strcmp(dc[i].y,dc[i+1].y)==0)
ans[dc[i+1].id]=ans[dc[i].id];
}
printf("Case %d\n",cas++);
for(int i=1; i<=n; i++) printf("%d\n",ans[i]);
del(root0);
del(root1);
puts("");
}
return 0;
}
版权声明:本文博客原创文章,博客,未经同意,不得转载。
[AC自己主动机] zoj Searching the String的更多相关文章
- ZOJ 3228 Searching the String (AC自己主动机)
题目链接:Searching the String 解析:给一个长串.给n个不同种类的短串.问分别在能重叠下或者不能重叠下短串在长串中出现的次数. 能重叠的已经是最简单的AC自己主动机模板题了. 不能 ...
- ZOJ - 3228 Searching the String (AC自己主动机)
Description Little jay really hates to deal with string. But moondy likes it very much, and she's so ...
- zoj 3430 Detect the Virus(AC自己主动机)
Detect the Virus Time Limit: 2 Seconds Memory Limit: 65536 KB One day, Nobita found that his co ...
- ZOJ 3494 BCD Code (AC自己主动机 + 数位DP)
题目链接:BCD Code 解析:n个病毒串.问给定区间上有多少个转换成BCD码后不包括病毒串的数. 很奇妙的题目. . 经典的 AC自己主动机 + 数位DP 的题目. 首先使用AC自己主动机,得到b ...
- AC自己主动机
AC自己主动机 AC自己主动机是KMP和Trie的结合,主要处理多模板串匹配问题.以下推荐一个博客,有助于学习AC自己主动机. NOTONLYSUCCESS 这里另一个Kuangbin开的比赛,大家 ...
- POJ 2778 DNA Sequence (AC自己主动机 + dp)
DNA Sequence 题意:DNA的序列由ACTG四个字母组成,如今给定m个不可行的序列.问随机构成的长度为n的序列中.有多少种序列是可行的(仅仅要包括一个不可行序列便不可行).个数非常大.对10 ...
- 【UVA】1449-Dominating Patterns(AC自己主动机)
AC自己主动机的模板题.须要注意的是,对于每一个字符串,须要利用map将它映射到一个结点上,这样才干按顺序输出结果. 14360841 1449 option=com_onlinejudge& ...
- POJ 3691 & HDU 2457 DNA repair (AC自己主动机,DP)
http://poj.org/problem?id=3691 http://acm.hdu.edu.cn/showproblem.php?pid=2457 DNA repair Time Limit: ...
- HDU 2896 病毒侵袭 AC自己主动机题解
本题是在text里面查找key word的增强版.由于这里有多个text. 那么就不能够简单把Trie的叶子标志记录改动成-1进行加速了,能够使用其它技术.我直接使用个vis数组记录已经訪问过的节点, ...
随机推荐
- DIKW模型与数据工程(了解)
DIKW 体系 DIKW体系是关于数据.信息.知识及智慧的体系,可以追溯至托马斯·斯特尔那斯·艾略特所写的诗--<岩石>.在首段,他写道:"我们在哪里丢失了知识中的智慧?又在哪里 ...
- 【u116】最短路计数
Time Limit: 1 second Memory Limit: 128 MB [问题描述] 给出一个N个顶点M条边的无向无权图,顶点编号为1-N.问从顶点1开始,到其他每个点的最短路有几条. [ ...
- python opencv3 —— findContours
findContours 是 opencv 下的轮廓提取函数. 1. api 分析 findContours(image, mode, method[, contours[, hierarchy[, ...
- 【编程】常见概念的理解 —— inplace、vanity url、vanilla(code/software)、编译、链接、build、(delegate、proxy)
inplace: 如修改一个文件等对象时, inplace=True,不创建新的对象,直接在原始对象上尽心修改: inplace=False,在对原始对象进行修改,而会创建新的对象: vanity u ...
- RFC chinese
rfc专业性强,现实中不可能有好的全的rfc的翻译 尝试上在github上搜索 https://github.com/tidyjiang8/6lowpan-rfcs-chinese 诚如作者所说: 在 ...
- Android EditText文本内容变化监听方法
package com.google; import android.app.Activity; import android.os.Bundle; import android.text.Edita ...
- 【u206】最大赢家
Time Limit: 1 second Memory Limit: 128 MB [问题描述] Nic和Susan在玩一个有趣的游戏:在游戏开始前,他们先约定一个正整数n,同时令m=1.游戏过程中, ...
- 项目中使用了个quartz包,启动时提示Quartz version update check failed
<span style="font-family: Arial, Helvetica, sans-serif;">2015-09-13 00:12:02 Abstrac ...
- 【机器学习实战】第12章 使用 FP-growth 算法来高效发现频繁项集
第12章 使用FP-growth算法来高效发现频繁项集 前言 在 第11章 时我们已经介绍了用 Apriori 算法发现 频繁项集 与 关联规则.本章将继续关注发现 频繁项集 这一任务,并使用 FP- ...
- 编写ATL控件的简单做法
作者:朱金灿 来源:http://blog.csdn.net/clever101 ATL并不像MFC库那样提供了很多的控件窗口类,因此要使用ATL的话需要自己去封装.封装的做法很简单.比如现在我需要一 ...