BZOJ2938 [Poi2000]病毒 和 BZOJ5261 Rhyme
[Poi2000]病毒
二进制病毒审查委员会最近发现了如下的规律:某些确定的二进制串是病毒的代码。如果某段代码中不存在任何一段病毒代码,那么我们就称这段代码是安全的。现在委员会已经找出了所有的病毒代码段,试问,是否存在一个无限长的安全的二进制代码。
示例:例如如果{011, 11, 00000}为病毒代码段,那么一个可能的无限长安全代码就是010101…。如果{01, 11, 000000}为病毒代码段,那么就不存在一个无限长的安全代码。
任务:请写一个程序:
- 读入病毒代码;
- 判断是否存在一个无限长的安全代码;
- 将结果输出
给出若干个 01 串,问是否存在一个无限长的 01 串,满足所有给出的串都不是它的子串.
jklover的题解
将给出的串插入到 AC 自动机里,那么若存在一个环,环上的节点及它们沿 fail 指针向上跳都不经过单词末节点,则符合要求.
插入的时候将权值一起合并,最后做一次 dfs 即可.
时间复杂度:线性。
co int N=3e4+1,S=2;
namespace AC
{
int idx;
int ch[N][S],fail[N],val[N];
void ins(char*s,int len)
{
int u=0;
for(int i=0;i<len;++i)
{
int k=s[i]-'0';
if(!ch[u][k])
ch[u][k]=++idx;
u=ch[u][k];
}
val[u]=1;
}
void getfail()
{
std::queue<int>Q;
for(int i=0;i<S;++i)
if(ch[0][i])
Q.push(ch[0][i]);
while(Q.size())
{
int u=Q.front();Q.pop();
for(int i=0;i<S;++i)
{
if(ch[u][i])
{
fail[ch[u][i]]=ch[fail[u]][i];
val[ch[u][i]]|=val[ch[fail[u]][i]];
Q.push(ch[u][i]);
}
else
ch[u][i]=ch[fail[u]][i];
}
}
}
int vis[N],inc[N];
int dfs(int u)
{
inc[u]=1;
for(int i=0;i<S;++i)
{
int v=ch[u][i];
if(inc[v])
return 1;
if(vis[v]||val[v])
continue;
vis[v]=1;
if(dfs(v))
return 1;
}
inc[u]=0;
return 0;
}
void solve()
{
puts(dfs(0)?"TAK":"NIE");
}
}
int n;
char buf[N];
int main()
{
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
read(n);
for(int i=1;i<=n;++i)
{
scanf("%s",buf);
AC::ins(buf,strlen(buf));
}
AC::getfail();
AC::solve();
return 0;
}
Rhyme
由于多次交换邮票没有满足所有人的需求,小Z被赶出了集邮部。无处可去的小Z决定加入音乐部,为了让音乐部的人注意到自己的才华,小Z想写一首曲子。为了让自己的曲子更好听,小Z找到了一些好听曲子作为模板。曲谱可以表示成只包含小写字母的字符串,小Z希望自己最终的曲谱中任意一个长度为K的子串都是一个模板的子串。现在小Z想知道自己的曲谱最长可以是多长,如果可以无限长的话请输出INF。
每组数据字符串总长不超过100000,1≤K≤100000。每个测试点数据不超过10组。
dummyummy的题解
可以先看一下这道题 [POI2000]病毒,虽然是个AC自动机,不过思路很像。
对于这道题,我们只需要把广义SAM建出来,然后在那些只经过maxlen⩾k的结点的路径中选一个最长的就行了。最后一步可以用拓扑排序来完成。
拓扑建边时可以直接向fail连边,而不是把儿子补全(像AC自动机那样ch[u][c]=ch[fail[u]][c]),这样能降低复杂度。
最后如果出现环,就输出INF,否则求最长路径,注意特判所有结点的maxlen都小于k的情况,题目最下方有说明。
时间复杂度\(O(\sum |s|)\)。
typedef pair<int,int> pii;
co int N=2e5+3;
int n,k;
char str[N];
int tot;
int ch[N][26],fa[N],len[N];
vector<pii> g[N];
int ind[N],dis[N];
void clear(){
for(int i=1;i<=tot+2;++i){
memset(ch[i],0,sizeof ch[i]);
g[i].clear(),ind[i]=dis[i]=0;
}
tot=1;
}
int extend(int p,int c){
int last;
if(ch[p][c]){
int q=ch[p][c];
if(len[q]==len[p]+1) last=q;
else{
int clone=last=++tot;
memcpy(ch[clone],ch[q],sizeof ch[q]);
fa[clone]=fa[q],len[clone]=len[p]+1;
fa[q]=clone;
for(;ch[p][c]==q;p=fa[p]) ch[p][c]=clone;
}
}
else{
int cur=last=++tot;
len[cur]=len[p]+1;
for(;p&&!ch[p][c];p=fa[p]) ch[p][c]=cur;
if(!p) fa[cur]=1;
else{
int q=ch[p][c];
if(len[q]==len[p]+1) fa[cur]=q;
else{
int clone=++tot;
memcpy(ch[clone],ch[q],sizeof ch[q]);
fa[clone]=fa[q],len[clone]=len[p]+1;
fa[cur]=fa[q]=clone;
for(;ch[p][c]==q;p=fa[p]) ch[p][c]=clone;
}
}
}
return last;
}
void Rhyme(){
clear();
for(int i=1;i<=n;++i){
scanf("%s",str+1);
int len=strlen(str+1),last=1;
for(int j=1;j<=len;++j) last=extend(last,str[j]-'a');
}
int s=tot+1,t=tot+2;
for(int i=1;i<=tot;++i){
if(len[i]==k-1){
for(int j=0;j<26;++j)if(ch[i][j]) g[i].push_back(pii(ch[i][j],1)),++ind[ch[i][j]];
g[s].push_back(pii(i,len[i])),++ind[i];
}
else if(len[i]>=k){
for(int j=0;j<26;++j)if(ch[i][j]) g[i].push_back(pii(ch[i][j],1)),++ind[ch[i][j]];
if(fa[i]&&len[fa[i]]>=k-1) g[i].push_back(pii(fa[i],0)),++ind[fa[i]];
g[i].push_back(pii(t,0)),++ind[t];
g[s].push_back(pii(i,len[i])),++ind[i];
}
}
if(!ind[t]) return printf("%d\n",k-1),void();
int ans=0;
queue<int> q;q.push(s);
for(int u;!q.empty();q.pop()){
u=q.front(),ans=max(ans,dis[u]);
for(int i=0,v;i<g[u].size();++i){
v=g[u][i].first,dis[v]=max(dis[v],dis[u]+g[u][i].second);
if(!--ind[v]) q.push(v);
}
}
for(int i=1;i<=tot;++i)if(ind[i]) return puts("INF"),void();
printf("%d\n",ans);
}
int main(){
while(~scanf("%d %d",&n,&k)) Rhyme();
return 0;
}
BZOJ2938 [Poi2000]病毒 和 BZOJ5261 Rhyme的更多相关文章
- [bzoj2938][Poi2000]病毒_AC自动机
病毒 bzoj-2938 Poi-2000 题目大意:给你n个01串,问是否存在一个无限长的01串使得这个01的任意子串都不等于给出的01串. 注释:All_length<=30,000 想法: ...
- BZOJ2938: [Poi2000]病毒(AC自动机)
2938: [Poi2000]病毒 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 1678 Solved: 849[Submit][Status][D ...
- bzoj2938: [Poi2000]病毒
建AC自动机,把所有病毒的节点都删掉,dfs判有没有环,有环就找得到. #include <iostream> #include <cstdio> #include <c ...
- BZOJ2938[Poi2000]病毒——AC自动机
题目描述 二进制病毒审查委员会最近发现了如下的规律:某些确定的二进制串是病毒的代码.如果某段代码中不存在任何一段病毒代码,那么我们就称这段代码是安全的.现在委员会已经找出了所有的病毒代码段,试问,是否 ...
- BZOJ2938:[POI2000]病毒(AC自动机)
Description 二进制病毒审查委员会最近发现了如下的规律:某些确定的二进制串是病毒的代码.如果某段代码中不存在任何一段病毒代码,那么我们就称这段代码是安全的.现在委员会已经找出了所有的病毒代码 ...
- BZOJ2938 [Poi2000]病毒 【AC自动机】
题目 二进制病毒审查委员会最近发现了如下的规律:某些确定的二进制串是病毒的代码.如果某段代码中不存在任何一段病毒代码,那么我们就称这段代码是安全的.现在委员会已经找出了所有的病毒代码段,试问,是否存在 ...
- BZOJ2938 POI2000病毒
我们不能让重复过的字串出现在无限串上(就叫这个了...) 也就是要自动机一直能匹配但就是匹配不到,那么就是在自动机上找一个环. dfs判环即可.注意是个有向图. #include<bits/st ...
- 【BZOJ2938】[Poi2000]病毒 AC自动机+DFS
[BZOJ2938][Poi2000]病毒 Description 二进制病毒审查委员会最近发现了如下的规律:某些确定的二进制串是病毒的代码.如果某段代码中不存在任何一段病毒代码,那么我们就称这段代码 ...
- 【BZOJ-2938】病毒 Trie图 + 拓扑排序
2938: [Poi2000]病毒 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 609 Solved: 318[Submit][Status][Di ...
随机推荐
- saltstack配置文件详解
软件依赖 Python版本大于2.6或版本小于3.0: 对Python版本要求 msgpack-python: SalStack消息交换库 YAML: SaltStack配置解析定义语法 Jinja2 ...
- kubelet tls
当成功签发证书后,目标节点的 kubelet 会将证书写入到 --cert-dir= 选项指定的目录中:此时如果不做其他设置应当生成上述除ca.pem以外的4个文件 kubelet-client.cr ...
- 【C++札记】指针数组和数组指针
指针数组: 存储指针的数组,数组找那个的每个一元素都是指针 例: int* p1[4],p2[0]是一个指向int类型的指针 char* p2[4],p1[0]是一个指向char类型的指针 数组指针: ...
- web渗透思维导图
更新中!!
- mysql实践一:SQL基础
mysql简介 mysql是有名的开放源代码关系型数据库.它最早是AB公司开源的,后来到Sun公司手中.之后Sun公司被Oracle公司收购,mysql就归Oracle所有.从此mysql走向商业化, ...
- 使用PHP开发HR系统(2)
本节讲述如何创建基于CI框架的PHP程序. ============================================================================== ...
- SpringBoot项目jar启动端口设置
SpringBoot项目打包后,在target下生成的jar文件可以使用 Java - jar 直接启动,指定端口号配置 java -jar epjs-eureka.jar --server.port ...
- 【题解】Luogu P5398 [Ynoi2018]GOSICK
原题传送门 二次离线莫队 二次离线莫队的做法参考第十四分块(前体)的题解 我们需要考虑从(1,i)如何推到(1,i+1) 我们算过了a[i]的答案,考虑加入a[i]的贡献 我们需要在a[i]的所有约数 ...
- Spring Cloud Alibaba学习笔记(19) - Spring Cloud Gateway 自定义过滤器工厂
在前文中,我们介绍了Spring Cloud Gateway内置了一系列的内置过滤器工厂,若Spring Cloud Gateway内置的过滤器工厂无法满足我们的业务需求,那么此时就需要自定义自己的过 ...
- Xinetd服务的安装与配置详解
1.什么是xinetd xinetd即extended internet daemon,xinetd是新一代的网络守护进程服务程序,又叫超级Internet服务器.经常用来管理多种轻量级Interne ...