考的时候脑子各种短路,用个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. ZOJ 3781 - Paint the Grid Reloaded - [DFS连通块缩点建图+BFS求深度][第11届浙江省赛F题]

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3781 Time Limit: 2 Seconds      Me ...

  2. HDU 5727 - Necklace - [全排列+二分图匹配][Hopcroft-Karp算法模板]

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5727 Problem DescriptionSJX has 2*N magic gems. ...

  3. SQL Fundamentals: Basic SELECT statement基本的select语句(控制操作的现实列)(FROM-SELECT)

    SQL Fundamentals || Oracle SQL语言 Capabilities of the SELECT Statement(SELECT语句的功能) Data retrieval fr ...

  4. TensorFlow指定GPU使用及监控GPU占用情况

    查看机器上GPU情况 命令: nvidia-smi 功能:显示机器上gpu的情况 命令: nvidia-smi -l 功能:定时更新显示机器上gpu的情况 命令:watch -n 3 nvidia-s ...

  5. js里常用函数之高阶函数

    高阶函数:将函数作为参数或者返回值的函数.将函数作为参数的用法通常称作回调函数,函数参数通常会在主函数被执行之后被高阶函数调用. 高阶函数的使用实例.可以把有相似操作的函数用一个高阶函数来重构,精简代 ...

  6. firmware 固件

    COMPPUTER SCIENCE AN OVERVIEW 11th Edition firmware 固件 boot loader 引导程序 device driver 设备驱动程序 Basic I ...

  7. 如何用 Keynote 制作动画演示(转)

    原文:如何用 Keynote 制作动画演示 Keynote 里的很多特效可以用来制作效果不错的演示,一页页的将需要演示的内容交代清楚后,直接输出成 m4v 的视频格式,为了方便贴到博客或者发布到 Tw ...

  8. 用 Python 替代 Bash 脚本(转)

    add by zhj: 其实作者是想说用Python来做那些Bash实现起来比较麻烦的部分,即将Bash与Python结合使用. 英文原文:http://www.linuxjournal.com/co ...

  9. 如何设置dedecms自定义表单必填项?

    用dedecms自定义表单可以制作一个简单的预约系统,有些相关信息需要设置为必填项,比如联系方式,没有留下真实的电话或其他信息,以后要怎么联系到你的客户.那我们要如何设置织梦cms自定义表单必填项呢? ...

  10. ListView多种item注意以及自己出现的莫名其妙的错误

    如果ListView不懂,请绕路 1.ListView添加多个item必须用到的两个方法 getViewTypeCount一共有多少种item,我这里写的两种 getItemViewType当前pos ...