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 ... 
随机推荐
- java 多线程争抢资源死锁
			多线程争抢资源死锁的原理就是,A线程正在持有锁1却想获取锁2,B线程正在持有锁2却要获取锁1 代码如下: public class Main { static ReentrantLock lock1 ... 
- Android 跨进程数据共享
			Android 开发过程中,基于功能隔离.进程安全.进程保活等等考虑,我们经常需要为应用划分进程,然后不得不面临跨进程通信和跨进程共享数据的挑战. 跨进程通信 相对来说,跨进程通信比较简单,常用的方式 ... 
- java的智能提示无法打开
			第一步:选中“window”->“preference” 第二步:选中“java”,并展开 第三步:选中“Editor”,并展开 第四步:选中“Content Assist”,在右侧 ... 
- LNMP分离式部署
			#### LNMP组合工作流程 在LNMP组合工作时,首先是用户通过浏览器输入域名请求Nginx Web服务,如果请求是静态资源,则由Nginx解析返回给用户:如果是动态请求(.php结尾),那么Ng ... 
- Python socket的客户端
			做一个socket客户端1.声明一个实例2.绑定端口号和地址3.循环发送和接收响应其中要注意粘包的产生,为了防止粘包的产生,应该在服务器端先测出要发送信息的大小,然后发送响应至客户端,等到服务器上一条 ... 
- C#保存日志文件到txt中,可追加保存,定时删除最后一次操作半年前日志文件
			/// <summary> /// 输出指定信息到文本文件 /// </summary> /// <param name="msg">输出信息& ... 
- ubuntu16.04 backup and restore
			http://blog.csdn.net/qq_35523593/article/details/78545530 
- WebApi接口访问异常问题。尝试创建“testController”类型的控制器时出错。请确保控制器具有无参数公共构造函数
			本来运行的好好的webAPI 接口突然报了个 :“尝试创建“testController”类型的控制器时出错.请确保控制器具有无参数公共构造函数” 错误.耗了半宿最终解决了, 原因: api控制器中引 ... 
- ASP.Net Core "The type initializer for 'Gdip' threw an exception"
			ASP.NET Core项目部署在Linux下可能会出现GDI错误 The type initializer for 'Gdip' threw an exception 解决方案:创建 libdl 的 ... 
- vue实现验证码倒计时60秒的具体代码
			vue实现验证码倒计时60秒的具体代码 <span v-show="show" @click="getCode">获取验证码</span> ... 
