考的时候脑子各种短路,用个SAM瞎搞了半天没搞出来,最后中午火急火燎的打了个SPFA才混了点分。

其实这个可以把每个模式串长度为$K-1$的字符串看作一个状态,这个用字符串Hash实现,然后我们发现这实际上可以通过不断转移变成一个DAG,通过topsort即可算出最优解。

我怎么就那么脑残没想到呢..

//rhyme
//by Cydiater
//2017.2.19
#include <iostream>
#include <cstdio>
#include <queue>
#include <map>
#include <cstring>
#include <string>
#include <algorithm>
#include <cstdlib>
#include <cstdio>
#include <ctime>
#include <cmath>
#include <bitset>
#include <set>
#include <vector>
#include <complex>
using namespace std;
#define ll long long
#define up(i,j,n)	for(int i=j;i<=n;i++)
#define down(i,j,n)	for(int i=j;i>=n;i--)
#define cmax(a,b)	a=max(a,b)
#define cmin(a,b)	a=min(a,b)
#define FILE		"rhyme"
#define Auto(i,node)	for(int i=LINK[node];i;i=e[i].next)
#define pii		pair<int,int>
#define Map		map<pii,int>
const int MAXN=3e5+5;
const int oo=0x3f3f3f3f;
const int base1=130069;
const int base2=136027;
const int mod1=9179767;
const int mod2=9832517;
inline int read(){
	char ch=getchar();int x=0,f=1;
	while(ch>'9'||ch<'0'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}
int N,K,cnt=1;
char s[MAXN];
struct Hash{
	int bin[MAXN],hash[MAXN],base,mod;
	void Ready(int Base,int Mod){
		base=Base;mod=Mod;
		int len=strlen(s+1);
		bin[0]=1;hash[0]=0;
		up(i,1,len){
			bin[i]=(1LL*bin[i-1]*base)%mod;
			hash[i]=(1LL*hash[i-1]*base%mod+s[i]-17+mod)%mod;
		}
	}
	int get(int L,int R){
		return ((hash[R]-1LL*hash[L-1]*bin[R-L+1]%mod+mod)%mod+mod)%mod;
	}
}h1,h2;
namespace Graph{
	struct edge{
		int y,next;
	}e[MAXN<<1];
	int LINK[MAXN],len=0,deg[MAXN],q[MAXN],head,tail,dis[MAXN];
	bool vis[MAXN];
	pii E[MAXN<<1];
	void reset(){
		len=0;
		memset(LINK,0,sizeof(LINK));
		memset(vis,0,sizeof(vis));
		memset(deg,0,sizeof(deg));
	}
	inline void insert(int x,int y){
		e[++len].next=LINK[x];LINK[x]=len;e[len].y=y;
		deg[y]++;E[len]=make_pair(x,y);
	}
	void Topsort(int cnt){
		head=1;tail=0;
		int tol=len;reset();len=tol;
		up(i,1,tol)insert(E[i].second,E[i].first);
		memset(dis,0,sizeof(dis));
		up(i,1,cnt)if(!deg[i]){
			q[++tail]=i;
			dis[i]=1;
		}
		for(;head<=tail;head++){
			int node=q[head];
			Auto(i,node)if(!--deg[e[i].y]){
				cmax(dis[e[i].y],dis[node]+1);
				q[++tail]=e[i].y;
			}
		}
		up(i,1,cnt)if(deg[i])dis[1]=oo;
	}
}
Map ID;
namespace solution{
	void Prepare(){
		Graph::reset();
		ID.erase(ID.begin(),ID.end());
		cnt=1;
		up(i,1,N){
			using namespace Graph;
			scanf("%s",s+1);int len=strlen(s+1);
			if(len<K)continue;
			h1.Ready(base1,mod1);h2.Ready(base2,mod2);
			pii last=make_pair(h1.get(1,K-1),h2.get(1,K-1)),now;
			if(!ID[last]){
				ID[last]=++cnt;
				insert(1,cnt);
			}
			up(j,K,len){
				now=make_pair(h1.get(j-K+2,j),h2.get(j-K+2,j));
				if(!ID[now]){
					ID[now]=++cnt;
					insert(1,cnt);
				}
				insert(ID[last],ID[now]);
				last=now;
			}
		}
	}
	void Solve(){
		Graph::Topsort(cnt);
		if(Graph::dis[1]==oo){
			puts("INF");
			return;
		}
		printf("%d\n",Graph::dis[1]+K-3==K-2?K-1:Graph::dis[1]+K-3);
	}
}
int main(){
	freopen(FILE".in","r",stdin);
	freopen(FILE".out","w",stdout);
	using namespace solution;
	while(scanf("%d%d",&N,&K)!=EOF){
		Prepare();
		Solve();
	}
	return 0;
}

[省选模拟]Rhyme的更多相关文章

  1. 【洛谷比赛】[LnOI2019]长脖子鹿省选模拟赛 T1 题解

    今天是[LnOI2019]长脖子鹿省选模拟赛的时间,小编表示考的不怎么样,改了半天也只会改第一题,那也先呈上题解吧. T1:P5248 [LnOI2019SP]快速多项式变换(FPT) 一看这题就很手 ...

  2. 省选模拟赛第四轮 B——O(n^4)->O(n^3)->O(n^2)

    一 稍微转化一下,就是找所有和原树差距不超过k的不同构树的个数 一个挺trick的想法是: 由于矩阵树定理的行列式的值是把邻接矩阵数值看做边权的图的所有生成树的边权乘积之和 那么如果把不存在于原树中的 ...

  3. NOI2019省选模拟赛 第五场

    爆炸了QAQ 传送门 \(A\) \(Mas\)的童年 这题我怎么感觉好像做过--我记得那个时候还因为没有取\(min\)结果\(100\to 0\)-- 因为是个异或我们肯定得按位考虑贡献了 把\( ...

  4. NOI2019省选模拟赛 第六场

    传送门 又炸了-- \(A\) 唐时月夜 不知道改了什么东西之后就\(A\)掉了\(.jpg\) 首先,题目保证"如果一片子水域曾经被操作过,那么在之后的施法中,这片子水域也一定会被操作&q ...

  5. 省选模拟赛 arg

    1 arg (arg.cpp/in/out, 1s, 512MB)1.1 Description给出一个长度为 m 的序列 A, 请你求出有多少种 1...n 的排列, 满足 A 是它的一个 LIS. ...

  6. 【NOI省选模拟】小奇的花园

    「题目背景」 小奇在家中的花园漫步时,总是会思考一些奇怪的问题. 「问题描述」 小奇的花园有n个温室,标号为1到n,温室以及以及温室间的双向道路形成一棵树. 每个温室都种植着一种花,随着季节的变换,温 ...

  7. [JZOJ6257] 【省选模拟8.9】修路

    题目 题目大意 有一堆点,每个点都有其权值\(c_i\). 每次插入边\((u,v)\),\(u\)和\(1\)连通,\(v\)和\(1\)不连通.最后保证形成一棵树. 每次插入的时候询问\(1\)到 ...

  8. @省选模拟赛03/16 - T3@ 超级树

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 一棵 k-超级树(k-SuperTree) 可按如下方法得到:取 ...

  9. 5.10 省选模拟赛 拍卖 博弈 dp

    LINK:拍卖 比赛的时候 前面时间浪费的有点多 写这道题的时候 没剩多少时间了. 随便设了一个状态 就开始做了. 果然需要认真的思考.其实 从我的状态的状态转移中可以看出所有的结论. 这里 就不再赘 ...

随机推荐

  1. Master Boot Record

    https://en.wikipedia.org/wiki/Master_boot_record https://zh.wikipedia.org/wiki/主引导记录 A master boot r ...

  2. 洛谷P3244 落忆枫音 [HNOI2015] 拓扑排序+dp

    正解:拓扑排序+dp 解题报告: 传送门 我好暴躁昂,,,怎么感觉HNOI每年总有那么几道题题面巨长啊,,,语文不好真是太心痛辣QAQ 所以还是要简述一下题意,,,就是说,本来是有一个DAG,然后后来 ...

  3. 易忘的mysql语句

    1.修改主键 ALTER TABLE `resource` DROP PRIMARY KEY ,ADD PRIMARY KEY ( `rid` ) 2.加上auto_increment ) NOT N ...

  4. 帝国cms底部代码哪里改?要修改版权和统计代码

    最近接手的几个站是用帝国cms做的,底部代码那边都有一个**设计的链接,还有一些不相关的东西,第一眼看到就想把那些帝国cms底部代码清理掉,这就是让别人建站的烦恼,让他们删除说要收费,坑就一个字,自己 ...

  5. Android应用之——百度地图最新SDK3.0应用,实现最经常使用的标注覆盖物以及弹出窗覆盖物

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/yanglfree/article/details/33333413 一.概述 最新版的百度地图SDK ...

  6. 腾讯云的云数据库MYSQL配置

    腾讯云的云数据库MYSQL配置

  7. host文件常用地址

    #+UPDATE_TIME 2016-02-16 19:52:05 UTC+8#+MESSAGE#################################################### ...

  8. 001-将自己的jar提交maven中央仓

    一.Maven中央仓库提交过程 ① https://issues.sonatype.org 工单管理地址,就是申请上传资格和groupId 的地方. ② https://oss.sonatype.or ...

  9. vue.js常用的

    <input v-model.number="age" type="number"> //自动将用户的输入值转为数值类型 <input v-m ...

  10. 万恶之源 - Python初识函数

    什么是函数 我们目前为止,已经可以完成一些软件的基本功能了,那么我们来完成这样一个功能:约x pint("拿出手机") print("打开陌陌") print( ...