考的时候脑子各种短路,用个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. HDU 2444 - The Accomodation of Students - [二分图判断][匈牙利算法模板]

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=2444 Time Limit: 5000/1000 MS (Java/Others) Mem ...

  2. iOS + Node + MySQL

    最近有空,又温习了一下Node ,配合Express 4.x可以很快的搭建一个简单的后台. Node比较适合频繁I/O,大量异步.至于更加复杂的后台逻辑还是用Java,个中滋味自己体验. Expres ...

  3. innodb next-key lock引发的死锁

    innodb的事务隔离级别是可重复读级别且innodb_locks_unsafe_for_binlog禁用,也就是说允许next-key lock CREATE TABLE `LockTest` (  ...

  4. golang语言中的context详解,Go Concurrency Patterns: Context

    https://blog.golang.org/context Introduction In Go servers, each incoming request is handled in its ...

  5. POJ:3083 Children of the Candy Corn(bfs+dfs)

    http://poj.org/problem?id=3083 Description The cornfield maze is a popular Halloween treat. Visitors ...

  6. 【Cocos2dx 3.3】图片裁剪

        从一个图片集中裁剪出需要的图片时,采用的坐标是屏幕坐标系:        示例如下:    图片:res/Images/grossini_dance_atlas.png ,每个人物大小为85* ...

  7. python3与mysql:创建表、插入数据54

    import pymysql db = pymysql.connect(host=',db='jodb1',port=3307,charset='utf8') # #测试连接开发库成功 # db = ...

  8. CentOS6.5安装Redis数据库

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

  9. linq to sql 左联接出错,未将对象引用设置到实例

    var result = from a in model join b in orderDetailModel on a.FoodMenuID equals b.FoodMenuID into g f ...

  10. mysql数据库给别人访问权限

    注:本操作是在WIN命令提示符下,phpMyAdmin同样适用. 用户:phplamp  用户数据库:phplampDB 1.新建用户. //登录MYSQL @>mysql -u root -p ...