考的时候脑子各种短路,用个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. ubuntu14.04下编译支持opengl的opencv

    在学习基于opencv的AR时,编译程序遇到报错,发现opencv不支持opengl.网上原因得知,在编译opencv时,opencv2.4以后的版本中默认ENABLE_OPENGL = NO,只需要 ...

  2. create view in view

    CREATE VIEW view_region2role AS ( SELECT region_set_id, region_set_name, GROUP_CONCAT(id) gc_id, GRO ...

  3. Ubuntu安装mysql及设置远程访问方法

    ubuntu上安装mysql非常简单只需要几条命令就可以完成. 1. sudo apt-get install mysql-server   2. apt-get isntall mysql-clie ...

  4. css3写等腰三角形

    <style>            .test {                width: 0;                height: 0;                b ...

  5. [py]python的继承体系-源码目录结构

    python3安装目录 pip install virtualenv pip install virtualenvwrapper pip install virtualenvwrapper-win m ...

  6. HDU1010:Tempter of the Bone(dfs+剪枝)

    http://acm.hdu.edu.cn/showproblem.php?pid=1010   //题目链接 http://ycool.com/post/ymsvd2s//一个很好理解剪枝思想的博客 ...

  7. http形式的webservice

    import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import ...

  8. 【SVM】A Practical Guide to Support Vector Classi cation

    零.简介 一般认为,SVM比神经网络要简单. 优化目标:

  9. soapUI-property Transfer

    1.1.1  Property Transfer 创建或双击现有的Property-Transfer TestStep将打开以下窗口: 左侧的列表显示了此TestStep中配置的传输,添加和管理所需的 ...

  10. CentOS6.5安装Redis数据库

    1.以安装redis2.8.19为例 下载安装包:http://redis.io tar zxvf redis-2.8.19.tar.gz #解压 cd redis-2.8.19 #进入解压后的文件夹 ...