BZOJ 5261 Rhyme
思路
考虑一个匹配的过程,当一个节点x向后拼接一个c的时候,为了满足题目条件的限制,应该向suflink中最深的len[x]+1>=k的节点转移(保证该后缀拼上一个c之后,长度为k的子串依然属于模板串的子串),然后拓扑求最长链即可,出现环就输出INF
代码
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
int Nodecnt,trans[250000][26],suflink[250000],maxlen[250000],n,k;
char s[250000];
int New_state(int _maxlen,int *_trans,int _suflink){
++Nodecnt;
maxlen[Nodecnt]=_maxlen;
if(_trans)
for(int i=0;i<26;i++)
trans[Nodecnt][i]=_trans[i];
suflink[Nodecnt]=_suflink;
return Nodecnt;
}
int add_len(int u,int c){
if(trans[u][c]){
int v=trans[u][c];
if(maxlen[v]==maxlen[u]+1){
return v;
}
int y=New_state(maxlen[u]+1,trans[v],suflink[v]);
suflink[v]=y;
while(u&&trans[u][c]==v){
trans[u][c]=y;
u=suflink[u];
}
return y;
}
else{
int z=New_state(maxlen[u]+1,NULL,0);
while(u&&trans[u][c]==0){
trans[u][c]=z;
u=suflink[u];
}
if(!u){
suflink[z]=1;
return z;
}
int v=trans[u][c];
if(maxlen[v]==maxlen[u]+1){
suflink[z]=v;
return z;
}
int y=New_state(maxlen[u]+1,trans[v],suflink[v]);
suflink[z]=suflink[v]=y;
while(u&&trans[u][c]==v){
trans[u][c]=y;
u=suflink[u];
}
return z;
}
}
int in[250000],use[250000],v[250000],nxt[250000],fir[250000],cnt,dp[250000];
void init(void){
Nodecnt=1;
memset(trans,0,sizeof(trans));
memset(suflink,0,sizeof(suflink));
memset(maxlen,0,sizeof(maxlen));
memset(in,0,sizeof(in));
memset(use,0,sizeof(use));
cnt=0;
memset(v,0,sizeof(v));
memset(nxt,0,sizeof(nxt));
memset(fir,0,sizeof(fir));
memset(dp,0,sizeof(dp));
}
void addedge(int ui,int vi){
++cnt;
v[cnt]=vi;
nxt[cnt]=fir[ui];
fir[ui]=cnt;
}
void dfs(int u){
if(use[u]){
for(int i=0;i<26;i++){
if(trans[u][i]&&use[trans[u][i]])
in[trans[u][i]]++;
else{
int p=u;
while(p&&(trans[p][i]==0||maxlen[p]+1<k))
p=suflink[p];
trans[u][i]=trans[p][i];
in[trans[p][i]]++;
}
}
for(int i=fir[u];i;i=nxt[i])
dfs(v[i]);
}
else
for(int i=fir[u];i;i=nxt[i])
dfs(v[i]);
}
queue<int> q;
int topu(void){
while(!q.empty())
q.pop();
for(int i=1;i<=Nodecnt;i++)
use[i]=(maxlen[i]>=k),addedge(suflink[i],i);
dfs(1);
int num=0;
for(int i=1;i<=Nodecnt;i++){
num+=use[i];
if(use[i]&&(!in[i]))
q.push(i),dp[i]=maxlen[i];
}
if(!num)
return k-1;
if(q.empty())
return 0x3f3f3f3f;
while(!q.empty()){
int x=q.front();
q.pop();
for(int i=0;i<26;i++){
if(trans[x][i]){
dp[trans[x][i]]=max(dp[trans[x][i]],dp[x]+1);
in[trans[x][i]]--;
if(!in[trans[x][i]])
q.push(trans[x][i]);
}
}
}
int ans=0;
for(int i=1;i<=Nodecnt;i++)
if(use[i]&&in[i])
return 0x3f3f3f3f;
else
ans=max(ans,dp[i]);
return ans;
}
int main(){
while(scanf("%d %d",&n,&k)==2){
init();
for(int i=1;i<=n;i++){
scanf("%s",s+1);
int len=strlen(s+1),last=1;
for(int j=1;j<=len;j++)
last=add_len(last,s[j]-'a');
}
int t=topu();
if(t==0x3f3f3f3f){
printf("INF\n");
}
else{
printf("%d\n",t);
}
}
return 0;
}
BZOJ 5261 Rhyme的更多相关文章
- BZOJ 2127: happiness [最小割]
2127: happiness Time Limit: 51 Sec Memory Limit: 259 MBSubmit: 1815 Solved: 878[Submit][Status][Di ...
- BZOJ 3275: Number
3275: Number Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 874 Solved: 371[Submit][Status][Discus ...
- BZOJ 2879: [Noi2012]美食节
2879: [Noi2012]美食节 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1834 Solved: 969[Submit][Status] ...
- bzoj 4610 Ceiling Functi
bzoj 4610 Ceiling Functi Description bzoj上的描述有问题 给出\(n\)个长度为\(k\)的数列,将每个数列构成一个二叉搜索树,问有多少颗形态不同的树. Inp ...
- BZOJ 题目整理
bzoj 500题纪念 总结一发题目吧,挑几道题整理一下,(方便拖板子) 1039:每条线段与前一条线段之间的长度的比例和夹角不会因平移.旋转.放缩而改变,所以将每条轨迹改为比例和夹角的序列,复制一份 ...
- 【sdoi2013】森林 BZOJ 3123
Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数.第三行包含N个非负整数 ...
- 【清华集训】楼房重建 BZOJ 2957
Description 小A的楼房外有一大片施工工地,工地上有N栋待建的楼房.每天,这片工地上的房子拆了又建.建了又拆.他经常无聊地看着窗外发呆,数自己能够看到多少栋房子. 为了简化问题,我们考虑这些 ...
- 【splay】文艺平衡树 BZOJ 3223
Description 您需要写一种数据结构(可参考题目标题),来维护一个有序数列,其中需要提供以下操作:翻转一个区间,例如原有序序列是5 4 3 2 1,翻转区间是[2,4]的话,结果是5 2 3 ...
- bzoj 刷水
bzoj 3856: Monster 虽然是sb题,,但是要注意h可能<=a,,,开始忘记判了WA得很开心. #include <iostream> #include <cst ...
随机推荐
- LeetCode 653 Two Sum IV - Input is a BST 解题报告
题目要求 Given a Binary Search Tree and a target number, return true if there exist two elements in the ...
- Zynq系列FPGA如何固化bit文件到QSPI_Flash
最近由于项目需要,要将bit文件固化到zedboard的flash中,使程序上电自启,断电不丢失. 我们知道,一般板级调试的时候都是直接下载bit流到FPGA就行,固化到Flash的话,也是先生成.m ...
- Dapper的应用
Dapper是一个轻型的开源ORM类,代码就一个SqlMapper.cs文件 using Dapper; using System; using System.Collections.Generic; ...
- table的thead,tbody,tfoot
为了让大表格(table)在下载的时候可以分段的显示,就是说在浏览器解析HTML时,table是作为一个整体解释的,使用tbody可以优化显示. 如果表格很长,用tbody分段,可以一部分一部分地显示 ...
- CentOS配置apache多站点设置
配置文件目录: /etc/httpd/conf.d /etc/httpd/conf/httpd.conf 错误日志文件在哪里? 网站文件目录: /var/www/html (Ubuntu/Centos ...
- Hadoop组件
---------Hive--------------------------zooKeeper-------------------------------kafka---------------- ...
- CDI services--Scope(生命周期)&&EL.(Sp El)
一.EL/SpEL 1.EL语言(CDI与表达式语言(EL)集成,允许在JavaServer Faces页面或JavaServer Pages页面中直接使用任何组件) 1)概述:EL是JSP内置的表达 ...
- 关于Ajax的认识和封装(小记)
一,Ajax 的概念 1,Ajax 是一种在无需重新加载整个网页(即刷新网页)的情况下,能够更新部分网页的技术. 2,Ajax 的全称是Asynchronous Javascript And XML” ...
- Rsync数据同步工具
Rsync数据同步工具 什么是Rsync? Rsync是一款开源的.快速的.多功能的,可以实现全量及增量的本地或原程数据同步备份 ...
- webpack入门文档教程
.octicon{margin-right:2px}a.tabnav-extra:hover{color:#4078c0;text-decoration:none}.tabnav-btn{margin ...